This is a bit tricky, since there are two operations involved,
the addition and the assignment. In order to avoid the copies,
you have to both modify the string in the addition, and
ensure that the assignment is a no-op. It's the second part
which is tricky.
What I've done on occasions is to create a custom "accumulator",
along the lines of:
class Accu
{
std::string myCollector;
enum DummyToSuppressAsgn { dummy };
public:
Accu( std::string const& startingValue = std::string() )
: myCollector( startingValue )
{
}
// Default copy ctor and copy asgn are OK.
// On the other hand, we need the following special operators
Accu& operator=( DummyToSuppressAsgn )
{
// Don't do anything...
return *this;
}
DummyToSuppressAsgn operator+( std::string const& other )
{
myCollector += other;
return dummy;
}
// And to get the final results...
operator std::string() const
{
return myCollector;
}
};
There'll be a few copies when calling accumulate
, and of the
return value, but during the actual accumulation, nothing. Just
invoke:
std::string results = std::accumulate( foo.begin(), foo.end(), Accu() );
(If you're really concerned about performance, you can add
a capacity argument to the constructor of Accu
, so that it can
do a reserve
on the member string. If I did this, I'd
probably hand write the copy constructor as well, to ensure that
the string in the copied object had the required capacity.)