title: Efficient accumulate
body: <p>Assume I have vector of strings and I want concatenate them via std::accumulate.</p>
  
  <p>If I use the following code:</p>
  
  <pre><code>std::vector&lt;std::string&gt; foo{"foo","bar"};
  string res=""; 
  res=std::accumulate(foo.begin(),foo.end(),res,
    [](string &amp;rs,string &amp;arg){ return rs+arg; });
  </code></pre>
  
  <p>I can be pretty sure there will be temporary object construction.</p>
  
  <p>In <a href="https://stackoverflow.com/a/13740937/754982">this</a> answer they say that the effect of std::accumulate is specified this way:</p>
  
  <blockquote>
    <p>Computes its result by initializing the accumulator acc with the
    initial value init and then modifies it with acc = acc + *i or acc =
    binary_op(acc, *i) for every iterator i in the range [first,last) in
    order.</p>
  </blockquote>
  
  <p>So I'm wondering what is the correct way to do this to avoid the unnecessary temporary object construction.</p>
  
  <p>One idea was to change the lambda this way:</p>
  
  <pre><code>[](string &amp;rs,string &amp;arg){ rs+=arg; return rs; }
  </code></pre>
  
  <p>In this case, I thought I force efficient concatenation of the strings and help the compiler (I know I <a href="http://www.youtube.com/watch?v=AKtHxKJRwp4" rel="nofollow noreferrer">shouldn't</a>) omit the unnecessary copy, since this should be equivalent to (pseudocode):</p>
  
  <pre><code>accum = [](&amp; accum,&amp; arg){ ...; return accum; }
  </code></pre>
  
  <p>and thus </p>
  
  <pre><code>accum = &amp; accum;
  </code></pre>
  
  <p>Another idea was to use </p>
  
  <pre><code>accum = [](&amp; accum,&amp; arg){ ...; return std::move(accum); }
  </code></pre>
  
  <p>But this would probably lead to something like:</p>
  
  <pre><code>accum = std::move(&amp; accum);
  </code></pre>
  
  <p>Which looks very suspicious to me.</p>
  
  <p>What is the correct way to write this to minimize the risk of the unnecessary creation of temporary objects? I'm not just interested in std::string, I'd be happy to have a solution, that would probably work for any object that has copy and move constructors/assignments implemented.</p>