2017-09-17 27 views
5

Po prostu uczę się STL i reverse_iterator ma mnie mylić. Ma domyślny konstruktor, ale nie rozumiem, jak go używać. Próbowałem:Dlaczego reverse_iterator ma domyślny konstruktor?

reverse_iterator<int*> r{}; 
r --; 

i program się zawiesił. Uważam, że nie ma sensu tego użycia i może łatwo spowodować awarię, więc dlaczego domyślny konstruktor może być używany?

+2

Prawdopodobnie tylko po to, aby potwierdzić, że "niezainicjowane" iteratory mają później przypisaną konkretną wartość. Po prostu traktuj konstrukcje domyślne jako zmienne niezainicjowane, tj. Nie rób z nimi nic, dopóki nie przydzielisz znaczącej wartości. – AnT

+0

Dlaczego można zdefiniować wskaźnik wskazujący na 'nullptr', a następnie usunąć go? Jest wiele rzeczy, które są dozwolone, a które są bardzo niebezpieczne, nawet niezdefiniowane. To właśnie nadaje C++ szybkość i status strzelania sobie w nogę. –

+0

@RickAstley Wierzę, że standardowa biblioteka C++ przeniosła się z mentalności "strzelaj do woli", "nie strzelisz do nóg, jeśli nic nie kosztuje". Musiałby istnieć jeszcze jeden powód, gdyby coś niebezpiecznego było dozwolone –

Odpowiedz

3

std::reverse_iteratorbidirectional iterators, które mają wyraźny wymóg, aby były domyślne.

Jeśli chodzi o why bidirectional iterators are default-constructible, to głównie dlatego, że jest prawie pewne, że są one łatwe do wdrożenia, a udzielanie gwarancji sprawia, że ​​algorytmy są łatwiejsze do wdrożenia.

Pisanie rzeczy takich jak int* p = nullptr; *p; samo w sobie jest UB, narusza warunek wstępny, że p jest dereferencyjne, pozwalając adaptatorom "adoptować" tego rodzaju zachowania jest raczej naturalne.

3

Dokumentacja na cppreference mówi:

1) konstruktor domyślny. prąd jest zainicjowany wartością. Operacje na wynikowym iteratorze mają zdefiniowane zachowanie wtedy i tylko wtedy, gdy odpowiednie operacje na inicjowanym wartościowo Iteratorze również mają określone zachowanie.

Istnieje kilka iteratorów, które mają znaczenie przy konstruowaniu domyślnym; zwykle nie te, które są bezpośrednio związane z kontenerami (o których mi wiadomo). Na przykład an iterator istream: http://en.cppreference.com/w/cpp/iterator/istream_iterator/istream_iterator. Nie jest to jednak dwukierunkowe, więc nie można go odwrócić.

Jednak w zasadzie można mieć iterator, który jest dwukierunkowy i którego domyślny inicjator konstruktora/wartości ma przynajmniej określone operacje. Dla takiego iteratora, chcesz, aby zachowanie zostało odzwierciedlone przez reverse_iterator.

Powiązane problemy