<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  </style>
</head>
<body>
<h1 id="for-stdvector-concatenation"><code>+</code> for <code>std::vector</code> concatenation</h1>
<ul>
<li>Document number: P0473R0</li>
<li>Date: 2016-10-13</li>
<li>Reply-to: David Sankel &lt;dsankel@bloomberg.net&gt;</li>
<li>Audience: Library Evolution</li>
</ul>
<h2 id="abstract">Abstract</h2>
<table border="1">
<tr>
<th>
before
</th>
<th>
after
</th>
</tr>
<tr>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">std::vector&lt;<span class="dt">int</span>&gt; all_names = get_names_from_a();
std::vector&lt;<span class="dt">int</span>&gt; tmp = get_names_from_b();
all_names.insert(
  all_names.end(),
  std::make_move_iterator(tmp.begin()),
  std::make_move_iterator(tmp.end()));
tmp = get_names_from_c();
all_names.insert(
  all_names.end(),
  std::make_move_iterator(tmp.begin()),
  std::make_move_iterator(tmp.end()));</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">const</span> std::vector&lt;<span class="dt">int</span>&gt; all_names = get_names_from_a() +
                                   get_names_from_b() +
                                   get_names_from_c();</code></pre></div>
</td>
</tr>
</table>
<p>Concatenating <code>vector</code>s is an extremely common operation yet it currently require complicated code. This paper is an attempt to remedy this situation. We propose overloading the <code>+</code> and <code>+=</code> operators for <code>vector</code> to abstract away the move iterators, better show intent, and allow more code to be <code>const</code>-correct.</p>
<h2 id="performance-implications">Performance Implications</h2>
<p>Prior to C++11, functions producing <code>std::vector</code> objects would typically take in a pointer where the result is to be placed. This is demonstrated in the following snippet.</p>
<div class="sourceCode"><pre class="sourceCode c++"><code class="sourceCode cpp"><span class="co">// Set the specified &#39;name_store&#39; to the names from the &quot;a&quot; resource.</span>
<span class="dt">void</span> get_names_from_a(std::vector&lt;string&gt;&amp; name_store);</code></pre></div>
<p>Since C++11, it is generally encouraged to return vectors directly. This new style has several benefits, not least of which is reasonability of the code.</p>
<div class="sourceCode"><pre class="sourceCode c++"><code class="sourceCode cpp"><span class="co">// Return the names from the &quot;a&quot; resource.</span>
std::vector&lt;string&gt; get_names_from_a();</code></pre></div>
<p>If the author happens to know a priori that several functions will be contributing to a vector <em>and</em> that high-performance is required, passing in a reference to the <code>vector</code> and contributing elements to the end may be preferred. Note, however, that we've lost the simple semantics in the above code and that the caller's usage as leaked into the function's interface.</p>
<div class="sourceCode"><pre class="sourceCode c++"><code class="sourceCode cpp"><span class="co">// Get names from the &quot;a&quot; resource and add them onto the end of the specified</span>
<span class="co">// &#39;name_store&#39;.</span>
<span class="dt">void</span> add_names_from_a(std::vector&lt;<span class="dt">int</span>&gt;&amp; name_store);</code></pre></div>
<p>The implementer may opt for a generic function instead if the compilation performance hit and extra complication are deemed worth the added flexibility.</p>
<div class="sourceCode"><pre class="sourceCode c++"><code class="sourceCode cpp"><span class="co">// Get names from the &quot;a&quot; resource and assign them to subsequent iterators of</span>
<span class="co">// the specified &#39;name_store&#39;. The specified &#39;OutputIterator&#39; must be an output</span>
<span class="co">// iterator that accepts values of type &#39;std::string&#39;.</span>
<span class="kw">template</span>&lt;<span class="kw">typename</span> OutputIterator&gt;
<span class="dt">void</span> add_names_from_a(OutputIterator name_store);</code></pre></div>
<p>However, most of the time the extra performance isn't needed and the extra genericity isn't warranted. What tops priorities is simplicity of specification and use.</p>
<div class="sourceCode"><pre class="sourceCode c++"><code class="sourceCode cpp"><span class="co">// Return the names from the &quot;a&quot; resource.</span>
std::vector&lt;string&gt; get_names_from_a();</code></pre></div>
<p>The proposed <code>+</code> operator for <code>std::vector</code> is intended to support this kind of code where simplicity of implementation is the primary concern. When folks need higher performance, they can continue to make their interfaces more sophisticated to achieve it.</p>
<h2 id="a-model-for-overloads">A model for + overloads</h2>
<p>It may come as a surprise that we're using <code>+</code>, which is usually associated with a numeric sum operation, with a seemingly unrelated type, <code>std::vector</code>. There is precedent with overloading operators with meanings completely unrelated to the original semantics, as with C++ streams, but here we can generalize the original semantics without abandoning its essence.</p>
<p><code>+</code> for numerics and <code>+</code> for <code>std::string</code> have in common certain properties. Namely, <code>a + (b + c) == (a + b) + c</code> for all values <code>a</code>, <code>b</code>, and <code>c</code>. Operations like this with the types they apply to are called semigroups in mathematics. The proposed <code>+</code> operator for vectors also forms a semigroup. This concept can be used as a guide for when and where the <code>+</code> operator can be overloaded in a consistent way.</p>
<p>Note that all the aformentioned <code>+</code> overloads also have a zero element <code>e</code> where <code>e + a = a + e = a</code> for all values <code>a</code>. Operations like this with the types they apply to are called monoids in mathematics. The default constructed values of all of numerics, <code>std::string</code>, and <code>std::vector</code> represent their corresponding zero elements with respect to <code>+</code>. Perhaps monoids would be an even better guide for overloading of the <code>+</code> operator.</p>
<h2 id="wording">Wording</h2>
<p>If the committee deems this is worth pursuing, wording will be provided.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Lets keep simple things simple by allowing <code>+</code> to be used for concatenating vectors.</p>
</body>
</html>
