<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 149: Insert should return iterator to first element inserted</title>
<meta property="og:title" content="Issue 149: Insert should return iterator to first element inserted">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue149.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="149"><a href="lwg-defects.html#149">149</a>. Insert should return iterator to first element inserted</h3>
<p><b>Section:</b> 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Andrew Koenig <b>Opened:</b> 1999-06-28 <b>Last modified:</b> 2016-11-12</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#sequence.reqmts">active issues</a> in [sequence.reqmts].</p>
<p><b>View all other</b> <a href="lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>Suppose that c and c1 are sequential containers and i is an
iterator that refers to an element of c.  Then I can insert a copy of
c1's elements into c ahead of element i by executing </p>

<blockquote>

<pre>c.insert(i, c1.begin(), c1.end());</pre>

</blockquote>

<p>If c is a vector, it is fairly easy for me to find out where the
newly inserted elements are, even though i is now invalid: </p>

<blockquote>

<pre>size_t i_loc = i - c.begin();
c.insert(i, c1.begin(), c1.end());</pre>

</blockquote>

<p>and now the first inserted element is at c.begin()+i_loc and one
past the last is at c.begin()+i_loc+c1.size().<br/>
<br/>
But what if c is a list?  I can still find the location of one    
past the last inserted element, because i is still valid.    
To find the location of the first inserted element, though,    
I must execute something like </p>

<blockquote>

<pre>for (size_t n = c1.size(); n; --n)
   --i;</pre>

</blockquote>

<p>because i is now no longer a random-access iterator.<br/>
<br/>
Alternatively, I might write something like </p>

<blockquote>

<pre>bool first = i == c.begin();
list&lt;T&gt;::iterator j = i;
if (!first) --j;
c.insert(i, c1.begin(), c1.end());
if (first)
   j = c.begin();
else
   ++j;</pre>

</blockquote>

<p>which, although wretched, requires less overhead.<br/>
<br/>
But I think the right solution is to change the definition of insert
so that instead of returning void, it returns an iterator that refers
to the first element inserted, if any, and otherwise is a copy of its
first argument.&nbsp; </p>

<p><i>[
Summit:
]</i></p>


<blockquote><p>
Reopened by Alisdair.
</p></blockquote>

<p><i>[
Post Summit Alisdair adds:
]</i></p>


<blockquote>
<p>
In addition to the original rationale for C++03, this change also gives a
consistent interface for all container insert operations i.e. they all
return an iterator to the (first) inserted item.
</p>

<p>
Proposed wording provided.
</p>
</blockquote>

<p><i>[
2009-07 Frankfurt
]</i></p>


<blockquote>
<p>
Q: why isn't this change also proposed for associative containers?
</p>

<p>
A: The returned iterator wouldn't necessarily point to a contiguous range.
</p>

<p>
Moved to Ready.
</p>
</blockquote>



<p id="res-149"><b>Proposed resolution:</b></p>
<p>
23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> Table 83
change return type from <code>void</code> to <code>iterator</code> for the following rows:
</p>

<blockquote>
<table border="1">
<caption>Table 83 &mdash; Sequence container requirements (in addition to container)</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Assertion&#47;note pre-&#47;post-condition</th>
</tr>
<tr>
<td>
<code>a.insert(p,n,t)</code>
</td>
<td>
<code><del>void</del> <ins>iterator</ins></code>
</td>
<td>
Inserts <code>n</code> copies of <code>t</code> before <code>p</code>.
</td>
</tr>

<tr>
<td>
<code>a.insert(p,i,j)</code>
</td>
<td>
<code><del>void</del> <ins>iterator</ins></code>
</td>
<td>
Each iterator in the range <code>[i,j)</code> shall be 
dereferenced exactly once. 
pre: <code>i</code> and <code>j</code> are not iterators into <code>a</code>. 
Inserts copies of elements in <code>[i, j)</code> before <code>p</code>
</td>
</tr>

<tr>
<td>
<code>a.insert(p,il)</code>
</td>
<td>
<code><del>void</del> <ins>iterator</ins></code>
</td>
<td>
<code>a.insert(p, il.begin(), il.end())</code>.
</td>
</tr>
</table>
</blockquote>

<p>
Add after p6 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a>:
</p>

<blockquote>
<p>-6- ...</p>

<p><ins>
The iterator returned from <code>a.insert(p,n,t)</code> points to the copy of the
first element inserted into <code>a</code>, or <code>p</code> if <code>n == 0</code>.
</ins></p>

<p><ins>
The iterator returned from <code>a.insert(p,i,j)</code> points to the copy of the
first element inserted into <code>a</code>, or <code>p</code> if <code>i == j</code>.
</ins></p>

<p><ins>
The iterator returned from <code>a.insert(p,il)</code> points to the copy of the
first element inserted into <code>a</code>, or <code>p</code> if <code>il</code> is empty.
</ins></p>

</blockquote>

<p>
p2 23.3.5 <a href="https://wg21.link/deque">[deque]</a> Update class definition, change return type
from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator position, size_type n, const T&amp; x);
template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, initializer_list&lt;T&gt;);
</pre></blockquote>

<p>
23.3.5.4 <a href="https://wg21.link/deque.modifiers">[deque.modifiers]</a> change return type from <code>void</code> to <code>iterator</code> on following declarations:
</p>

<blockquote><pre>
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, size_type n, const T&amp; x);
template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);
</pre></blockquote>

<p>
Add the following (missing) declaration
</p>

<blockquote><pre>
<ins>iterator insert(const_iterator position, initializer_list&lt;T&gt;);</ins>
</pre></blockquote>

<p>
 [forwardlist] Update class definition, change return type
from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert_after(const_iterator position, initializer_list&lt;T&gt; il);
<del>void</del> <ins>iterator</ins> insert_after(const_iterator position, size_type n, const T&amp; x);
template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert_after(const_iterator position, InputIterator first, InputIterator last);
</pre></blockquote>

<p>
p8  [forwardlist.modifiers] change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert_after(const_iterator position, size_type n, const T&amp; x);
</pre></blockquote>

<p>
Add paragraph:
</p>

<blockquote><p>
Returns: position.
</p></blockquote>

<p>
p10  [forwardlist.modifiers] change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert_after(const_iterator position, InputIterator first, InputIterator last);
</pre></blockquote>

<p>
Add paragraph:
</p>

<blockquote><p>
Returns: position.
</p></blockquote>

<p>
p12  [forwardlist.modifiers] change return type from <code>void</code> to <code>iterator</code> on following declarations:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert_after(const_iterator position, initializer_list&lt;T&gt; il);
</pre></blockquote>

<p>
change return type from <code>void</code> to <code>iterator</code> on following declarations:
</p>

<p>
p2 23.3.11 <a href="https://wg21.link/list">[list]</a> Update class definition, change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator position, size_type n, const T&amp; x);

template &lt;class InputIterator&gt;
<del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);

<del>void</del> <ins>iterator</ins> insert(const_iterator position, initializer_list&lt;T&gt;);
</pre></blockquote>

<p>
23.3.11.4 <a href="https://wg21.link/list.modifiers">[list.modifiers]</a> change return type from <code>void</code> to <code>iterator</code> on following declarations:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator position, size_type n, const T&amp; x);

template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);
</pre></blockquote>

<p>
Add the following (missing) declaration
</p>

<blockquote><pre>
iterator insert(const_iterator position, initializer_list&lt;T&gt;);
</pre></blockquote>

<p>
p2 23.3.13 <a href="https://wg21.link/vector">[vector]</a>
</p>

<p>
Update class definition, change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator position, T&amp;&amp; x);

<del>void</del> <ins>iterator</ins> insert(const_iterator position, size_type n, const T&amp; x);

template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);

<del>void</del> <ins>iterator</ins> insert(const_iterator position, initializer_list&lt;T&gt;);
</pre></blockquote>

<p>
23.3.13.5 <a href="https://wg21.link/vector.modifiers">[vector.modifiers]</a> change return type from <code>void</code> to <code>iterator</code> on following declarations:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator position, size_type n, const T&amp; x);

template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);
</pre></blockquote>

<p>
Add the following (missing) declaration
</p>

<blockquote><pre>
iterator insert(const_iterator position, initializer_list&lt;T&gt;);
</pre></blockquote>


<p>
p1 23.3.14 <a href="https://wg21.link/vector.bool">[vector.bool]</a> Update class definition, change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert (const_iterator position, size_type n, const bool&amp; x);

template &lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator position, InputIterator first, InputIterator last);

  <del>void</del> <ins>iterator</ins> insert(const_iterator position, initializer_list&lt;bool&gt; il);
</pre></blockquote>

<p>
p5 27.4.3 <a href="https://wg21.link/basic.string">[basic.string]</a> Update class definition, change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator p, size_type n, charT c);

template&lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator p, InputIterator first, InputIterator last);

<del>void</del> <ins>iterator</ins> insert(const_iterator p, initializer_list&lt;charT&gt;);
</pre></blockquote>

<p>
p13 27.4.3.7.4 <a href="https://wg21.link/string.insert">[string.insert]</a> change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator p, size_type n, charT c);
</pre></blockquote>

<p>
Add paragraph:
</p>

<blockquote><p>
<i>Returns:</i> an iterator which refers to the copy of the first inserted
character, or <code>p</code> if <code>n == 0</code>.
</p></blockquote>

<p>
p15 27.4.3.7.4 <a href="https://wg21.link/string.insert">[string.insert]</a> change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
template&lt;class InputIterator&gt;
  <del>void</del> <ins>iterator</ins> insert(const_iterator p, InputIterator first, InputIterator last);
</pre></blockquote>

<p>
Add paragraph:
</p>

<blockquote><p>
<i>Returns:</i> an iterator which refers to the copy of the first inserted
character, or <code>p</code> if <code>first == last</code>.
</p></blockquote>

<p>
p17 27.4.3.7.4 <a href="https://wg21.link/string.insert">[string.insert]</a> change return type from <code>void</code> to <code>iterator</code>:
</p>

<blockquote><pre>
<del>void</del> <ins>iterator</ins> insert(const_iterator p, initializer_list&lt;charT&gt; il);
</pre></blockquote>

<p>
Add paragraph:
</p>

<blockquote><p>
<i>Returns:</i> an iterator which refers to the copy of the first inserted
character, or <code>p</code> if <code>il</code> is empty.
</p></blockquote>



<p><b>Rationale:</b></p>

<p><i>[
The following was the C++98&#47;03 rationale and does not necessarily apply to the
proposed resolution in the C++0X time frame:
]</i></p>


<blockquote>
<p>The LWG believes this was an intentional design decision and so is
not a defect. It may be worth revisiting for the next standard.</p>
</blockquote>




</body>
</html>
