<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2183: Muddled allocator requirements for match_results constructors</title>
<meta property="og:title" content="Issue 2183: Muddled allocator requirements for match_results constructors">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2183.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++20">C++20</a> status.</em></p>
<h3 id="2183"><a href="lwg-defects.html#2183">2183</a>. Muddled allocator requirements for <code>match_results</code> constructors</h3>
<p><b>Section:</b> 28.6.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a>, 28.6.9.7 <a href="https://wg21.link/re.results.all">[re.results.all]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Pete Becker <b>Opened:</b> 2012-08-29 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="lwg-index.html#re.results.const">issues</a> in [re.results.const].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>

<p>
28.6.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> p1 says:
</p>
<blockquote><p>
In all <code>match_results</code> constructors, a copy of the <code>Allocator</code> argument shall be used for any memory 
allocation performed by the constructor or member functions during the lifetime of the object.
</p></blockquote>
<p>
There are three constructors:
</p>
<blockquote><pre>
match_results(const Allocator&amp; = Allocator());
match_results(const match_results&amp; m);
match_results(match_results&amp;&amp; m) noexcept;
</pre></blockquote>
<p>
The second and third constructors do no have an <code>Allocator</code> argument, so despite the "all <code>match_results</code> 
constructors", it is not possible to use "the <code>Allocator</code> argument" for the second and third constructors.
<p/>
The requirements for those two constructors also does not give any guidance. The second constructor has no language 
about allocators, and the third states that the stored <code>Allocator</code> value is move constructed from 
<code>m.get_allocator()</code>, but doesn't require using that allocator to allocate memory.
<p/>
The same basic problem recurs in 28.6.9.7 <a href="https://wg21.link/re.results.all">[re.results.all]</a>, which gives the required return value for 
<code>get_allocator()</code>:
</p>
<blockquote><p>
<i>Returns</i>: A copy of the <code>Allocator</code> that was passed to the object's constructor or, if that allocator 
has been replaced, a copy of the most recent replacement.
</p></blockquote>
<p>
Again, the second and third constructors do not take an <code>Allocator</code>, so there is nothing that meets this 
requirement when those constructors are used.
</p>

<p><i>[2018-06-02, Daniel comments and provides wording]</i></p>

<p>
The introductory wording of <code>match_results</code> says in 28.6.9 <a href="https://wg21.link/re.results">[re.results]</a> p2:
</p>
<blockquote><p>
The class template <code>match_results</code> satisfies the requirements of an allocator-aware container and of a sequence
container (26.2.1, 26.2.3) except that only operations defined for const-qualified sequence containers are
supported and that the semantics of comparison functions are different from those required for a container.
</p></blockquote>
<p>
This wording essentially brings us to 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> which describes in p8 in general the
usage of allocators:
</p>
<blockquote><p>
[&hellip;] Copy constructors for these container types obtain an allocator by calling <code>allocator_traits&lt;allocator_
type&gt;::select_on_container_copy_construction</code> on the allocator belonging to the container being copied.
Move constructors obtain an allocator by move construction from the allocator belonging to the container being moved.
[&hellip;]
</p></blockquote>
<p>
The constructors referred to in the issue discussion are the copy constructor and move constructor of <code>match_results</code>,
so we know already what the required effects are supposed to be.
<p/>
23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> p8 also says more to this allocator topic a bit latter:
</p>
<blockquote><p>
[&hellip;] All other constructors for these container types take a <code>const allocator_type&amp;</code> argument. 
[<i>Note:</i> If an invocation of a constructor uses the default value of an optional allocator argument, then the 
Allocator type must support value-initialization. &mdash; <i>end note</i>] A copy of this allocator is used for any 
memory allocation and element construction performed, by these constructors and by all member functions, during the 
lifetime of each container object or until the allocator is replaced.
[&hellip;]
</p></blockquote>
<p>
Further requirements imposed on two of the three <code>match_results</code> constructors can be derived from Table 80 &mdash; 
"Allocator-aware container requirements" via the specified expressions
</p>
<blockquote><pre>
X()
X(m)
X(rv)
</pre></blockquote>
<p>
In other words: The existing wording does already say <em>everything</em> that it said by 28.6.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> p1 (end 
even more), except for possibly the tiny problem that
</p>
<blockquote><pre>
match_results(const Allocator&amp; a = Allocator());
</pre></blockquote>
<p>
uses "<code>const Allocator&amp;</code>" instead of "<code>const allocator_type&amp;</code>" in the signature, albeit even 
that deviation shouldn't change the intended outcome, which is IMO crystal-clear when looking at sub-clauses 
23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> and 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> as a whole.
<p/>
That directly makes two mutually exclusive solutions feasible:
</p>
<ul>
<li><p>Either strike 28.6.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> p1 completely; or</p></li>
<li><p>Replace 28.6.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> p1 by referring to the specification of allocators in
23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> and 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a>.</p></li>
</ul>
<p>
My suggestion is to favour for the first option, because attempting to provide extra wording that refers to allocators
and the three constructors may lead to the false impression that no further allocator-related
requirements hold for type <code>match_results</code> which are not explicitly repeated here again.
</p>

<p><i>[2018-06, Rapperswil]</i></p>

<p>
The group agrees with the provided resolution. Move to Ready.
</p>

<p><i>[2018-11, Adopted in San Diego]</i></p>



<p id="res-2183"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4750">N4750</a>.</p>

<ol>
<li><p>Edit 28.6.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> as indicated:</p>
<blockquote>
<p>
<del>-1- In all <code>match_results</code> constructors, a copy of the <code>Allocator</code> argument shall be used for any memory allocation
performed by the constructor or member functions during the lifetime of the object.</del>
</p>
</blockquote>
</li>
</ol>





</body>
</html>
