vector<string> v(10, "foo");
string concat = accumulate(v.begin(), v.end(), string(""));
This example is simply bad programming, in any C++ standard. It is equivalent to this:
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 move semantics will only take care of the "copy the result back into tmp" part of the equation. The initial copies from tmp will still be copies. It is a classic Schlemiel the Painter's algorithm, but even worse than the usual example using strcat
in C.
If accumulate
just used +=
instead of +
and =
then it would've avoided all those copies.
But C++11 does give us a way to do better, while remaining succinct, using range for
:
string concat;
for (const string &s : v) { concat += s; }
EDIT: I suppose a standard library vendor could choose to implement accumulate
with move on the operand to +
, so tmp = tmp + "foo"
would become tmp = move(tmp) + "foo"
, and that would pretty much solve this problem. I'm not sure if such an implementation would be strictly conforming. Neither GCC, MSVC, nor LLVM do this in C++11 mode. And as accumulate
is defined in <numeric>
one might assume it is only designed for use with numeric types.
EDIT 2: As of C++20 accumulate
has been redefined to use move
as in the suggestion of my previous edit. I still consider it a questionable abuse of an algorithm that was only ever designed for use with arithmetic types.