W standardowej C++ projektu (N3485), stwierdza następujące:Dlaczego operator std :: unique_ptr * throw i operator-> nie rzuca?
20.7.1.2.4 unique_ptr obserwatorów [unique.ptr.single.observers]
typename add_lvalue_reference<T>::type operator*() const;
1 Requires: get() != nullptr.
2 Returns: *get().
pointer operator->() const noexcept;
3 Requires: get() != nullptr.
4 Returns: get().
5 Note: use typically requires that T be a complete type.
Widać, że operator*
(dereferencja) nie jest określona jako noexcept
, prawdopodobnie dlatego, że może spowodować uszkodzenie, ale następnie operator->
dla tego samego obiektu jest określone jako noexcept
. Wymagania dla obu są takie same, jednak istnieje różnica w specyfikacji wyjątków.
Zauważyłem, że mają różne typy zwrotu, jeden zwraca wskaźnik, a drugi referencję. Czy to powiedzenie, że operator->
w rzeczywistości niczego nie dereferencji?
Faktem jest, że za pomocą operator->
na wskaźnik dowolnego rodzaju, który jest NULL, będzie segfault (jest UB). Dlaczego więc jeden z nich jest określony jako noexcept
, a drugi nie?
Jestem pewien, że coś przeoczyłem.
EDIT:
Patrząc na std::shared_ptr
mamy to:
20.7.2.2.5 shared_ptr obserwatorzy [util.smartptr.shared.obs]
T& operator*() const noexcept;
T* operator->() const noexcept;
To nie to samo ? Czy to ma coś wspólnego z inną semantyką własności?
"Czy to powiedzenie, że operator-> faktycznie niczego nie usuwa?" Tak, to jest to –
Może to pozwolić implementacjom na wyrzucenie zerowego wskaźnika, jeśli tak zdecydują. – Dan