vector<string> v(10, "foo");
string concat = accumulate(v.begin(), v.end(), string(""));
Этот пример - просто плохое программирование на любом стандарте C++. Это эквивалентно следующему:
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
C++ 11 двигаться семантика будет принимать только заботиться о «копировать результат обратно в TMP» части уравнения. Начальные копии от tmp все равно будут копиями. Это классический Schlemiel the Painter's algorithm, но еще хуже, чем обычно, например, с использованием strcat
в С.
Если accumulate
просто использовали +=
вместо +
и =
тогда это было бы избежать всех этих копий.
Но C++ 11 действительно дает нам возможность сделать лучше, оставаясь при этом лаконичным, используя функцию лямбды:
string concat;
for_each(v.begin(), v.end(), [&](const string &s){ concat += s; });
EDIT: Я полагаю, стандартная библиотека реализатор может выбрать для реализации accumulate
с ходом на операнд +
, так что tmp = tmp + "foo"
стал бы tmp = move(tmp) + "foo"
, и это решило бы эту проблему. Я не уверен, что такая реализация будет строго соответствовать. В настоящее время ни GCC, ни MSVC, ни LLVM не делают этого. А так как accumulate
определен в <numeric>
, можно предположить, что он предназначен только для использования с числовыми типами.
Вот еще один ответ по теме: http://stackoverflow.com/questions/637695/how-efficient-is-stdstring-compared-to-null-terminated-strings/637737#637737 –