Questo è così facile che mi stupisce quante persone intelligenti hanno avvitato in su.
C++ 03:
std::string s;
for (std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i)
s += *i;
return s;
C++ 11: (la MSVC2010 sottoinsieme)
std::string s;
std::for_each(v.begin(), v.end(), [&](const std::string &piece){ s += piece; });
return s;
C++ 11:
std::string s;
for (const auto &piece : v) s += piece;
return s;
Non utilizzare std::accumulate
per la concatenazione di stringhe, è un classico Schlemiel the Painter's algorithm, anche peggio del solito esempio che utilizza strcat
in C. Senza la semantica di spostamento C++ 11, incorre in due copie non necessarie dell'accumulatore per ciascun elemento del vettore . Anche con la semantica del movimento, si incorre comunque in una copia non necessaria dell'accumulatore per ogni elemento.
I tre esempi sopra riportati sono O (n).
std::accumulate
è O (n^2) per stringhe.
Si potrebbe fare std::accumulate
O (n) per le stringhe, fornendo un funtore personalizzato:
std::string s = std::accumulate(v.begin(), v.end(), std::string{},
[](std::string &s, const std::string &piece) -> decltype(auto) { return s += piece; });
noti che s
deve essere un riferimento al non-const, il tipo di ritorno lambda deve essere un riferimento (quindi decltype(auto)
) e il corpo deve utilizzare +=
non +
.
Forse 'res std :: string; per (...) {res + = * it; } '? –