2015-04-28 38 views
6

Czy istnieje jakiś powód, że często widzę ten konstrukt:Czy powinienem używać operatora + = zamiast operatora + do łączenia std :: string?

std::string myString = someString + "text" + otherString + "more text"; 

... zamiast tego (co bardzo rzadko zobaczyć):

std::string myString; 
myString += someString += "text" += otherString += "more text"; 

Czytając std::string API, wydaje mi się, że operator+ tworzy dużo tymczasowych (być może zoptymalizowanych przez kompilator RVO?), podczas gdy wariant operator+= dołącza tylko tekst.

W niektórych przypadkach będzie można wybrać wariant operator+. Ale gdy potrzebujesz tylko dodać tekst do istniejącego nie-stałego ciągu, dlaczego nie po prostu użyć operator+=? Każdy powód, by tego nie robić?

-Rein

+0

Ostatnim razem, gdy mierzyłem wydajność, szybciej było robić wiele '+ =' niż '=' z wieloma '+' – Morb

+5

Czy chcesz zmodyfikować 'otherString' i' someString'? –

+0

Nie sądzę, że jedna forma byłaby zoptymalizowana nad drugą. Mamy elizację kopiowania i poruszamy teraz semantykę. @Morb Kiedy faktycznie użyto _astego czasu__ i jakich poziomów optymalizacji użyłeś? –

Odpowiedz

7

operator+= ma niewłaściwy rodzaj skojarzeń, aby napisać kod jak swoim drugim przykładzie. Aby to zrobić, co chcesz, to trzeba wspornik go tak:

(((myString += someString) += "text") += otherString) += "more text"; 

alternatywnie, co daje czytelność i wydajność chcesz, jest użycie std::stringstream:

std::stringstream myString; 
myString << someString << "text" << otherString << "more text"; 
+0

Brakuje tego faktu o powiązaniach operatora. Dziękuję za wskazanie. – raapeland

1

Zobacz

std::string aaa += bbb; 

jest podobna do

std::string aaa = aaa + bbb; 

, więc na Twój przykład zostanie zmieniony someString i otherString. W zwykłych przypadkach nie musisz martwić się o tymczasowe użycie operatora + - w trybie zwolnienia wszystkie zostaną usunięte (RVO i/lub inna optymalizacja).

+0

Nie sądzę, że komentarz optymalizacyjny jest prawdziwy, operator będzie nadal wywoływany, to nie będzie magicznie nie wykonywać dodatkowych przydziałów pamięci. – paulm

+0

Hmm, wszystkie główne kompilatory C++ używały optymalizacji RVO (możesz przeczytać o tym w opisie kompilatorów). Ta optymalizacja zależy od flag kompilatora: zwykle zmienia się w tryb "debugowania" i włącza się w trybie "wydania". W innym przypadku wszystkie pojemniki standardowe mają konstruktory ruchów, które wywoływane są, gdy nie można zastosować RVO. Nie będzie więc * dodatkowej * alokacji pamięci. – AeroSun