2009-11-03 22 views

Odpowiedz

16

Dodawanie będzie działać tylko z iteratorami dostępu losowego. std :: advance będzie działał z różnymi rodzajami iteratorów. Dopóki masz do czynienia z iteratorami tylko w wektorach, nie robi to żadnej różnicy, ale std :: advance utrzymuje twój kod bardziej ogólny (np. Możesz zastąpić listę dla wektora, a ta część nadal by działała).

Edit: Dla tych, którzy dbają, norma opisuje advance i distance następująco (§24.3.4/1):

Ponieważ tylko iteratory o dostępie swobodnym zapewniają + i - operatorów, biblioteka udostępnia dwie funkcje szablony advance i distance. Te szablony funkcji używają dla iteratorów o dostępie swobodnym (ang. Random access iterators) następujących pojęć + i (i dlatego są dla nich stałym czasem); w przypadku iteratorów wejściowych, do przodu i dwukierunkowych używają one ++ do zapewnienia linearnych implementacji czasu.

+12

Z drugiej strony użycie mniej ogólnego kodu uniemożliwi niechcący pesymizowanie kodu: w końcu może nie być dobrym pomysłem wykonywanie wielu "losowego dostępu" z kontenerem listy. – UncleBens

0

To zależy od iteratora. it=it+5 jest szybszy, jeśli jest obsługiwany (jest obsługiwany tylko w iteratorach dostępu losowego). Jeśli chcesz awansować mniej zdolnego iteratora (na przykład iteratora forward lub iteratora dwukierunkowego), możesz użyć parametru std::advance, ale jest wolniejszy, ponieważ faktycznie przechodzi przez wszystkie elementy pośrednie.

+1

Mylisz się, że standard dyktuje, że std :: advance jest liniowy dla sekwencji dostępu losowego: "Złożoność: Stały czas, jeśli InputIterator jest modelem iteratora dostępu swobodnego, inaczej liniowego." – Blindy

+1

std :: advance to stały czas dla iteratorów dostępu swobodnego (§24.3.4/1). –

+0

Nie sądzę, że to prawda w przypadku iteratorów dostępu losowego - std :: advance powinien być tak wydajny, jak operator + w tym przypadku. – Kylotan

0

std::advance działa również na nielosowych iteratorach, podczas gdy wersja += działa na sekwencjach dostępu losowego (wektorach i tym podobnych).

0

std::adnvance jest ogólna - przydaje się, jeśli nie zawsze wiesz, typ podstawowego pojemnika - działa we wszystkich przypadkach.

Jednak jest skuteczny: std::advance zrobi optymalizację gdyby zdał RandomAccessIterator (jak jeden z std::vector) i wzrośnie w pętli iteracyjnej dla ForwardAccessIterator (jak jak jeden w std::list).

0

Użyj std :: advance. Jest równie skuteczny (wykorzystuje iteratory po prostu do dodawania iteratorów dla iteratorów dostępu swobodnego) i jest bardziej ogólny, ponieważ działa również na inne rodzaje iteratorów.

7

To zależy od tego, czego potrzebujesz:

Jeśli potrzebujesz genericity, użyj std::advance(it,2). Jeśli ktoś przyjdzie i zmieni Twój na std::list, kod nadal będzie się kompilował, nawet jeśli przesuwanie teraz zajmuje liniowy czas zamiast stałego czasu.

Jeśli potrzebujesz wydajność, użyj it+=2. Jeśli ktoś przyjdzie i zmieni numer std::vector na std::list, kod nie powiedzie się, wskazując (może z przydatnym komentarzem) poważny problem z wydajnością.

0

Jeśli nigdy nie zamierzasz zmienić kontenera (a prawdopodobnie tak nie jest), użyj +, ponieważ jest łatwy do zrozumienia i zrozumienia, a kod jest mniej zagracony.

Jeśli uważasz, że chcesz zmienić kontener, LUB jeśli pracujesz w szablonie, który może być utworzony na różnych typach kontenerów, skorzystaj z góry, ponieważ działa z niczym.

Generalnie nie martwię się o zmianę typów kontenerów, ponieważ odkryłem, że kiedy muszę zmienić typ kontenera, wracam do każdego miejsca, w którym ten pojemnik jest używany, po prostu dla pewności "Nie robię niczego, co jest nagle głupie (jak wyrywkowe wyrywanie elementów ze środka listy).