<!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="single-argument-stdinserter">Single argument <code>std::inserter</code></h1>
<ul>
<li>Document number: P0471R0</li>
<li>Date: 2016-10-14</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;std::string&gt; vec = <span class="co">/* ... */</span>;
std::set&lt;std::string&gt; set;
std::copy(vec.begin(), vec.end(), std::inserter(set, set.begin()));</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">std::vector&lt;std::string&gt; vec = <span class="co">/* ... */</span>;
std::set&lt;std::string&gt; set;
std::copy(vec.begin(), vec.end(), std::inserter(set));</code></pre></div>
</td>
</tr>
</table>
<p><code>std::inserter</code> is most commonly used for copying data from a <code>vector</code> to something like a <code>set</code> where <code>std::back_inserter</code> doesn't work. Search your code base for usages of <code>std::inserter</code> and you'll discover the &quot;hint&quot; argument is consistently and indiscriminately either the container's begin or end iterator. Because this &quot;hint&quot; is never used to hint anything, we propose an overload of the <code>std::inserter</code> function template that has a single container parameter and returns a corresponding insert iterator. This change in the standard library would simplify a common operation that is a challenge to both teach and explain.</p>
<h2 id="the-chosen-iterator">The Chosen Iterator</h2>
<p>The proposed single argument version of <code>std::inserter</code> must choose an iterator to pass on to the <code>std::insert_iterator</code> it constructs. There are three possibilities. Given a passed container <code>x</code>, we can</p>
<ul>
<li>always use <code>x.begin()</code>,</li>
<li>always use <code>x.end()</code>, or</li>
<li>leave it unspecified.</li>
</ul>
<p>These options are semantically equivalent for containers like <code>std::set</code>. This choice has more important consequences on order preserving types like <code>std::vector</code>. It is the opinion of the author that the choice of least surprise is to always use <code>x.end()</code>.</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>This minor change improves readability by better supporting the most common usage pattern. Minor improvements like this could go a long way towards improving C++'s ability keep simple code simple.</p>
</body>
</html>
