This SO question wywołał dyskusję na temat std::generate
i gwarancji wykonanych przez standard. W szczególności, czy możesz używać obiektów funkcji ze stanem wewnętrznym i polegać na generate(it1, it2, gen)
, aby zadzwonić pod numer gen()
, zapisać wynik w *it
, ponownie zadzwonić pod numer gen()
, zapisać w numerze *(it + 1)
, lub czy może on rozpocząć się od tyłu?Standardowe sformułowanie C++: Czy "przez wszystkie iteratory w zasięgu" implikuje sekwencyjność?
normy (n3337, §25.3.7/1), to mówi:
efektów: pierwszy algorytm wywołuje obiekt funkcji
gen
i przypisuje się wartość powrotną gen przez wszystkie iteratorami w zakresie[first,last)
. Drugi algorytm wywołuje funkcję obiektu gen i przypisuje wartość zwracaną przez gen przez wszystkie iteratory w zakresie[first,first + n)
, jeślin
jest dodatnia, w przeciwnym razie nie robi nic.
Wydaje się, że nie zamawianie jest gwarantowany, zwłaszcza, że inne paragrafy mają mocniejsze brzmienie, na przykład std::for_each
(efekty: Dotyczy f
do wyniku wyłuskania każdą iterację w zakresie [first,last)
, począwszy od pierwszego i przejściem do last - 1
Jeśli przyjmujemy to dosłownie, gwarantuje to tylko rozpoczęcie od first
i kończy się na last
- brak gwarancji na zamówienie pomiędzy).
Ale: Zarówno Microsoft's i Apache's C++ standard library zarówno podać przykłady na swoich stronach dokumentacji, które wymagają oceny być sekwencyjna. I zarówno libC++ (w algorithm
) jak i libstdC++ (w bits/stl_algo.h
) implementują to w ten sposób. Co więcej, tracisz wiele potencjalnych aplikacji dla generate
bez tej gwarancji.
Czy obecne sformułowanie implikuje sekwencyjność? Jeśli nie, czy było to niedopatrzenie ze strony członków komitetu czy celowe?
(Wiem, że niewielu ludzi może dostarczyć wnikliwych odpowiedzi na to pytanie, nie spekulując ani nie dyskutując, ale moim skromnym zdaniem nie czyni to pytanie "nie konstruktywnym" zgodnie z wytycznymi SO .)
Dzięki @juanchopanza za wskazanie tego problemu i powołując mnie do ust o for_each
.
Nie sądzę 'generate()' jest bardzo przydatna, jeśli nie jest sekwencyjnym. –
Wierzę, że nieostrość jest znacznie podnoszona, gdy jest wzięta w kontekście wymaganej iteratora * klasy * funkcja szablonu nakazuje jej dostarczenie; ** 'szablon' **. Ponieważ zarówno pierwszy, jak i ostatni są wymagane tylko do przodu, z wyjątkiem umieszczenia ich wszystkich w tablicy lub konstrukcie wektorowym, a następnie niesekwencyjnie przeskakujących o sekwencji, nie ma wielkiego wyboru, tylko zacząć od początku i dotrzeć do końca. –
WhozCraig
@WhozCraig Heh, całkowicie to przegapiłem. Moim zdaniem jest to wnikliwa odpowiedź i należy ją opublikować jako taką. Niemniej jednak nadal chciałbym usłyszeć od osób bliskich komisji lub realizatorów bibliotek o swoich przemyśleniach na ten temat. – us2012