2013-10-06 13 views
8

Reading robocza Projekt N3337-1 Standard dla języka programowania C++, iteratory 24.2.5 przodu, strona 806.Co to jest gwarancja wieloprzebiegowa zgodnie ze standardem ISO C++?

Od projektu:

Dwa dereferenceable Iteratory a i b typu X oferta gwarancji multi-przejścia jeżeli:
- a == b implikuje ++a == ++b i
- X jest rodzajem wskaźnika lub wyrażenie (void)++X(a), *a jest równoznaczne z wyrażeniem *a.

[Uwaga: Wymóg a == b implikuje ++a == ++b (co nie jest prawdą dla iteratorów wejściowych i wyjściowych) i usuwanie ograniczeń dotyczących liczby zadań przez zmienny iterator (co dotyczy iteratorów wyjściowych) pozwala na korzystanie wieloprzebiegowych algorytmów jednokierunkowych z dalszymi iteratorami. -end note]

Czy ktoś mógłby ponownie zinterpretować to w łatwiejszy sposób? Rozumiem, że Forward iteratory są wieloprzebiegowe, ale nie rozumiem, w jaki sposób jest to realizowane zgodnie ze standardowymi wymaganiami C++.

+1

+1 Bo uważam, że jest to odpowiednie dla tej społeczności, nawet jeśli nie rozwiązuje konkretnego problemu programistycznego i trudno jest naprawdę przeczytać C++ Standard. – LihO

Odpowiedz

13

Terminy oznajmiają, że wszystko: myślę, że możesz przejść sekwencję kilka razy i zapamiętać pozycje w sekwencji. Dopóki sekwencja się nie zmieni, zaczynając od określonej pozycji (iteratora) będziesz przemierzać te same obiekty tak często, jak chcesz w tej samej kolejności. Możesz jednak iść tylko do przodu, nie ma sposobu na cofnięcie się. Kanonicznym przykładem takiej sekwencji jest pojedynczo połączona lista.

Cytowana klauzula w zasadzie mówi, że jeśli masz dwa iteratory porównując równy i przyrost każdy z nich można dostać się do tej samej pozycji i ich porównanie równa ponownie:

if (it1 == it2) { 
    ++it1; 
    ++it2; 
    assert(it1 == it2); // has to hold for multi-pass sequences 
} 

Nieco dziwne wyrażenie ++X(a), *a jest zasadniczo przeznaczony do rozwijania iteratora niezależnego od a, a wymóg, że ++X(a), *a jest równoważny z *a, zasadniczo oznacza, że ​​iterator w sekwencji przy użyciu niezależnego iteratora nie zmienia tego, co dotyczy. Inaczej jest w przypadku iteratora wejściowego, gdzie ++InIt(a), *a niekoniecznie jest równoważne z *a, ponieważ pierwsze wyrażenie może zmienić pozycję, prawdopodobnie unieważniając a i/lub zmieniając wartość, do której się odnosi.

W przeciwieństwie do tego sekwencja jednoprzebiegowa (wejściowe i wyjściowe iteracje w standardowych terminach) może być wykonywana tylko raz: próba wielokrotnego przejścia przez sekwencję nie będzie działać. Kanoniczny przykład takich sekwencji jest wprowadzany z klawiatury i wyprowadzany na konsolę: po odczytaniu nie można odzyskać tych samych znaków, a po wysłaniu nie można cofnąć znaków.