vector<string> v(10, "foo");
string concat = accumulate(v.begin(), v.end(), string(""));
Cet exemple est tout simplement une mauvaise programmation, dans toute norme C++. Il est équivalent à ceci:
string tmp;
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
tmp = tmp + "foo"; //copy tmp, append "foo", then copy the result back into tmp
11 C++ sémantique de mouvement ne fera que prendre soin de la partie « copier à nouveau le résultat dans tmp » de l'équation. Les copies initiales de tmp seront toujours des copies. Il est un classique Schlemiel the Painter's algorithm, mais encore pire que l'exemple habituelle en utilisant strcat
en C.
Si accumulate
juste utilisé +=
au lieu de +
et =
alors il aurait évité toutes ces copies.
Mais C++ 11 ne nous donne un moyen de faire mieux, tout en restant concis, en utilisant une fonction lambda:
string concat;
for_each(v.begin(), v.end(), [&](const string &s){ concat += s; });
EDIT: Je suppose que l'implémentation d'bibliothèque standard pourrait choisir de mettre en œuvre accumulate
avec mouvement sur l'opérande à +
, donc tmp = tmp + "foo"
deviendrait tmp = move(tmp) + "foo"
, et cela résoudrait à peu près ce problème. Je ne suis pas sûr qu'une telle implémentation serait strictement conforme. Ni GCC, MSVC, ni LLVM ne le font actuellement. Et comme accumulate
est défini dans <numeric>
, on peut supposer qu'il est conçu uniquement pour une utilisation avec des types numériques.
Voici une autre réponse à propos du sujet: http://stackoverflow.com/questions/637695/how-efficient-is-stdstring-compared-to-null-terminated-strings/637737#637737 –