2013-02-21 22 views
11

Chciałbym uzyskać porady dotyczące korzystania z BOOST_FOREACH.BOOST_FOREACH versus dla pętli

Przeczytałem, że nie jest to zalecane, jeśli chodzi o wydajność, która jest bardzo ciężkim nagłówkiem.

Co więcej, wymusza użycie instrukcji "break" i "continue", ponieważ nie można tak naprawdę uzyskać warunku wyjścia opartego na wartości logicznej Boolean i zawsze mówiono mi, że należy unikać "przerwania" i "kontynuowania". kiedy możliwe.

Oczywiście korzyści nie wiążą się bezpośrednio z iteratorami, które ułatwiają wykonywanie iteracji przez kontener.

Co o tym sądzisz? Czy sądzisz, że jeśli zostanie zastosowana, powinna być systematycznie adoptowana w celu zagwarantowania jednorodności projektu lub jego użycie jest zalecane tylko w określonych okolicznościach?

+4

"i zawsze mi mówiono, że należy unikać" przerwy "i" kontynuowania ", jeśli to możliwe." Czy możesz się z nim zapoznać? – utnapistim

+8

IIRC Były powody, by unikać przerwy i kontynuować z powrotem w dawnych dobrych czasach, kiedy ludzie nie mieli wzorów RAII, a optmimizery mogą mieć problemy, gdy pętle będą zbyt "skoczne". Były to dni dogmatu "single entry one exit", w którym funkcje miały tylko jedno oświadczenie zwrotne, tonę if's i some goto's.I są ludzie, którzy nauczyli się tych dogmatów eony temu, nigdy ich nie kwestionowali i rozpowszechniają wśród młodych ludzi w czasach, w których nie mają sensu, ale mają mnóstwo problemów. –

+0

Chociaż zgadzam się z tobą, muszę powiedzieć, że może nie być wartości w używaniu przerwy lub kontynuowania pętli. Jeśli zarezerwować te słowa kluczowe, aby podczas pętli i nie zgadza się z nich korzystać w pętli, intencją staje się wyraźniejszy. Ale to zbyt wiele IMHO, nie radziłbym tego. – MatiasFG

Odpowiedz

18

Powiedziałbym, że pętle bazujące na C++ zastępują go. Jest to odpowiednik this BOOST_FOREACH example:

std::string hello("Hello, world!"); 
for (auto c : hello) 
{ 
    std::cout << c; 
} 

Nigdy nie znalazłem musiałem go używać w ++ 03.

Uwaga przy użyciu pętli oparciu zakres, w pojemnikach z drogi skopiować elementy, albo w sposób ogólny kontekst, to najlepiej używać const& do tych elementów:

SomeContainerType<SomeType> v = ....; 
for (const auto& elem : v) 
{ 
    std::cout << elem << " "; 
} 

Podobnie, jeśli ned zmodyfikuj elementy kontenera, użyj nieokreślonego & (auto& elem : v).

+0

Myślę, że powinieneś używać [const] auto i przez większość czasu - w przeciwnym razie otrzymasz kopię – Daniel

+0

bardziej szczegółowy opis: http://msdn.microsoft.com/en-us/library/vstudio/dd293667.aspx (Referencje i cv -qualifiers) – Daniel

+0

@Daniel tak, ale int jego przypadku mamy pojedyncze 'char's i starałem napisać odpowiednik' przykład BOOST_FOREACH'. – juanchopanza

7

W programowaniu klarowność jest atutem. Zawsze używałam foreach do boost w C++ 03, stwierdziłem, że jest dużo czytelniejszy niż ręcznie pisana pętla, rozmiar nagłówka nie zabije cię. Jak słusznie zauważyłem @juanchopanza, to pytanie jest oczywiście przestarzałe w C++ 11.

Twoje obawy dotyczące zerwania i kontynuacji są bezpodstawne i prawdopodobnie przynoszą skutek odwrotny do zamierzonego. Z tradycyjnie długimi nagłówkami pętli for C++ 03 ludzie mają tendencję do , a nie odczytywania nagłówka pętli i do przeoczenia jakichkolwiek zmiennych warunkowych, które ukrywają się w nagłówku pętli. Lepiej zrób wyraźne intencje z przerwą i kontynuuj.

Jeśli zdecydowałeś się użyć foru boost, używaj go systematycznie. W końcu ma on zastąpić pętle z masłem.

0

Właśnie zastąpiłem użycie BOOST_FOREACH prostą pętlą for i otrzymałem 50% przyspieszenia, więc powiedziałbym, że zdecydowanie nie jest to najlepsze rozwiązanie. Nie otrzymasz również licznika pętli (np. "I"), który czasami faktycznie potrzebujesz. Osobiście nie jestem fanem, ale YMMV, jeśli lepiej pasuje do Twojego stylu.

BTW - "ciężki nagłówek" nie wpłynie na wydajność programu, tylko czas kompilacji.