<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3526: Return types of uses_allocator_construction_args unspecified</title>
<meta property="og:title" content="Issue 3526: Return types of uses_allocator_construction_args unspecified">
<meta property="og:description" content="C++ library issue. Status: C++23">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3526.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++23">C++23</a> status.</em></p>
<h3 id="3526"><a href="lwg-defects.html#3526">3526</a>. Return types of <code>uses_allocator_construction_args</code> unspecified</h3>
<p><b>Section:</b> 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a> <b>Status:</b> <a href="lwg-active.html#C++23">C++23</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2021-02-25 <b>Last modified:</b> 2023-11-22</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#allocator.uses.construction">active issues</a> in [allocator.uses.construction].</p>
<p><b>View all other</b> <a href="lwg-index.html#allocator.uses.construction">issues</a> in [allocator.uses.construction].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++23">C++23</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The synopsis of <code>&lt;memory&gt;</code> in 20.2.2 <a href="https://wg21.link/memory.syn">[memory.syn]</a> declares six overloads of 
<code>uses_allocator_construction_args</code> with return types "<i>see below</i>":
</p>
<blockquote><pre>
template&lt;class T, class Alloc, class... Args&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  Args&amp;&amp;... args) noexcept -&gt; <i>see below</i>;
template&lt;class T, class Alloc, class Tuple1, class Tuple2&gt;>
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc, piecewise_construct_t,
                                                  Tuple1&amp;&amp; x, Tuple2&amp;&amp; y)
                                                  noexcept -&gt; see below;
template&lt;class T, class Alloc&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc) noexcept -&gt; <i>see below</i>;
template&lt;class T, class Alloc, class U, class V&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  U&amp;&amp; u, V&amp;&amp; v) noexcept -&gt; <i>see below</i>;
template&lt;class T, class Alloc, class U, class V&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  const pair&lt;U, V&gt;&amp; pr) noexcept -&gt; <i>see below</i>;
template&lt;class T, class Alloc, class U, class V>
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  pair&lt;U, V&gt;&amp;&amp; pr) noexcept -&gt; <i>see below</i>;
</pre></blockquote>
<p>
The "<i>see below</i>s" also appear in the detailed specification of these overloaded function templates 
in 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a> para 4 through 15. Despite that the values these function 
templates return are specified therein, the return types are not. Presumably LWG wanted to specify deduced 
return types, but couldn't figure out how to do so, and just gave up?
</p>

<p><i>[2021-02-27; Daniel comments and provides wording]</i></p>

<p>
My interpretation is that the appearance of the <i>trailing-return-type</i> was actually unintended and that
these functions where supposed to use the return type placeholder to signal the intention that the actual
return type is deduced by the consistent sum of all return statements as they appear in the prototype specifications.
Given that at least one implementation has indeed realized this form, I suggest to simply adjust the specification
to remove the <i>trailing-return-type</i>. Specification-wise we have already existing practice for this 
approach (See e.g. <code>to_address</code>).
</p>

<p><i>[2021-03-12; Reflector poll]</i></p>

<p>
Set priority to 3 following reflector poll.
</p>


<p><i>[2021-05-26; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after nine votes in favour during reflector poll.
</p>

<p><i>[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting &rarr; WP.]</i></p>



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

<ol>
<li><p>Edit 20.2.2 <a href="https://wg21.link/memory.syn">[memory.syn]</a>, header <code>&lt;memory&gt;</code> synopsis, as indicated:</p>

<blockquote>
<pre>
namespace std {
  [&hellip;]
  <i>// 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a>, uses-allocator construction</i>
  template&lt;class T, class Alloc, class... Args&gt;
    constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                    Args&amp;&amp;... args) noexcept <del>-&gt; <i>see below</i></del>;
  template&lt;class T, class Alloc, class Tuple1, class Tuple2&gt;
    constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc, piecewise_construct_t,
                                                    Tuple1&amp;&amp; x, Tuple2&amp;&amp; y)
                                                    noexcept <del>-&gt; <i>see below</i></del>;
  template&lt;class T, class Alloc&gt;
    constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc) noexcept <del>-&gt; <i>see below</i></del>;
  template&lt;class T, class Alloc, class U, class V&gt;
    constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                    U&amp;&amp; u, V&amp;&amp; v) noexcept <del>-&gt; <i>see below</i></del>;
  template&lt;class T, class Alloc, class U, class V&gt;
    constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                    const pair&lt;U, V&gt;&amp; pr) noexcept <del>-&gt; <i>see below</i></del>;
  template&lt;class T, class Alloc, class U, class V&gt;
    constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                    pair&lt;U, V&gt;&amp;&amp; pr) noexcept <del>-&gt; <i>see below</i></del>;   
  [&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Edit 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, class Alloc, class... Args&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  Args&amp;&amp;... args) noexcept <del>-&gt; <i>see below</i></del>;
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-5- <i>Returns:</i> A <code>tuple</code> value determined as follows:
</p>
<ol style="list-style-type: none">
<li><p>(5.1) &mdash; if [&hellip;], return <code>forward_as_tuple(std::forward&lt;Args&gt;(args)...)</code>.</p></li>
<li><p>(5.2) &mdash; Otherwise, if [&hellip;], return</p>
<blockquote><pre>
tuple&lt;allocator_arg_t, const Alloc&amp;, Args&amp;&amp;...&gt;(
  allocator_arg, alloc, std::forward&lt;Args&gt;(args)...)
</pre></blockquote>
</li>
<li><p>(5.3) &mdash; Otherwise, if [&hellip;], return <code>forward_as_tuple(std::forward&lt;Args&gt;(args)..., alloc)</code>.</p></li>
<li><p>(5.4) &mdash; Otherwise, the program is ill-formed.</p></li>
</ol>
</blockquote>
<pre>
template&lt;class T, class Alloc, class Tuple1, class Tuple2&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc, piecewise_construct_t,
                                                  Tuple1&amp;&amp; x, Tuple2&amp;&amp; y)
                                                  noexcept <del>-&gt; <i>see below</i></del>;
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-7- <i>Effects:</i> For <code>T</code> specified as <code>pair&lt;T1, T2&gt;</code>, equivalent to:
</p>
<blockquote><pre>
return make_tuple(
  piecewise_construct,
  apply([&amp;alloc](auto&amp;&amp;... args1) {
          return uses_allocator_construction_args&lt;T1&gt;(
            alloc, std::forward&lt;decltype(args1)&gt;(args1)...);
        }, std::forward&lt;Tuple1&gt;(x)),
  apply([&amp;alloc](auto&amp;&amp;... args2) {
          return uses_allocator_construction_args&lt;T2&gt;(
            alloc, std::forward&lt;decltype(args2)&gt;(args2)...);
        }, std::forward&lt;Tuple2&gt;(y)));
</pre></blockquote>
</blockquote>
<pre>
template&lt;class T, class Alloc&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc) noexcept <del>-&gt; <i>see below</i></del>;
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-9- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return uses_allocator_construction_args&lt;T&gt;(alloc, piecewise_construct,
                                           tuple&lt;&gt;{}, tuple&lt;&gt;{});
</pre></blockquote>
</blockquote>
<pre>
template&lt;class T, class Alloc, class U, class V&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  U&amp;&amp; u, V&amp;&amp; v) noexcept <del>-&gt; <i>see below</i></del>;
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-11- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return uses_allocator_construction_args&lt;T&gt;(alloc, piecewise_construct,
                                           forward_as_tuple(std::forward&lt;U&gt;(u)),
                                           forward_as_tuple(std::forward&lt;V&gt;(v));
</pre></blockquote>
</blockquote>
<pre>
template&lt;class T, class Alloc, class U, class V&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  const pair&lt;U, V&gt;&amp; pr) noexcept <del>-&gt; <i>see below</i></del>;
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-13- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return uses_allocator_construction_args&lt;T&gt;(alloc, piecewise_construct,
                                           forward_as_tuple(pr.first),
                                           forward_as_tuple(pr.second));
</pre></blockquote>
</blockquote>
<pre>
template&lt;class T, class Alloc, class U, class V&gt;
  constexpr auto uses_allocator_construction_args(const Alloc&amp; alloc,
                                                  pair&lt;U, V&gt;&amp;&amp; pr) noexcept <del>-&gt; <i>see below</i></del>;
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-15- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return uses_allocator_construction_args&lt;T&gt;(alloc, piecewise_construct,
                                           forward_as_tuple(std::move(pr).first),
                                           forward_as_tuple(std::move(pr).second));
</pre></blockquote>
</blockquote>
</blockquote>
</li>

</ol>





</body>
</html>
