<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2303: Explicit instantiation of std::vector&lt;UserType&gt; broken?</title>
<meta property="og:title" content="Issue 2303: Explicit instantiation of std::vector&lt;UserType&gt; broken?">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2303.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#New">New</a> status.</em></p>
<h3 id="2303"><a href="lwg-active.html#2303">2303</a>. Explicit instantiation of <code>std::vector&lt;UserType&gt;</code> broken?</h3>
<p><b>Section:</b> 17.6.3.4 <a href="https://wg21.link/new.delete.placement">[new.delete.placement]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2013-09-18 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="lwg-index.html#new.delete.placement">issues</a> in [new.delete.placement].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The library gives explicit permission in 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> p2 that user code may explicitly instantiate
a library template provided that the instantiations depend on at least one user-defined type:
</p>

<blockquote><p>
A program may explicitly instantiate a template defined in the standard library only if the declaration
depends on the name of a user-defined type and the instantiation meets the standard library requirements
for the original template.
</p></blockquote>

<p>
But it seems that the C++11 library is not specified in a way that guarantees such an instantiation to be well-formed
if the minimum requirements of the library is not satisfied. 
<p/>
For example, in general, the first template parameter of <code>std::vector</code> is not required to be 
<code>DefaultConstructible</code> in general, but due to the split of the single C++03 member function
with default argument
</p>
<blockquote><pre>
void resize(size_type sz, T c = T());
</pre></blockquote>
<p>
into
</p>
<blockquote><pre>
void resize(size_type sz);
void resize(size_type sz, const T&amp; c);
</pre></blockquote>
<p>
the effect is now that for a type <code>ND</code> that is not <code>DefaultConstructible</code>, such as
</p>
<blockquote><pre>
struct NP { 
  NP(int); 
};
</pre></blockquote>
<p>
the explicit instantiation of <code>std::vector&lt;ND&gt;</code> is no longer well-formed, because the attempt to
instantiate the single-argument overload of <code>resize</code> cannot not succeed, because this function imposes
the <code>DefaultInsertable</code> requirements and given the default allocator this effectively requires
<code>DefaultConstructible</code>.
</p>
<p>
But <code>DefaultConstructible</code> is not the only point, what about <code>CopyConstructible</code> versus
<code>MoveConstructible</code> alone? It turns out that currently the second <code>resize</code> overload
would fail during an explicit instantiation for a type like
</p>
<blockquote><pre>
struct MO { 
  MO() = default; 
  MO(MO&amp;&amp;) = default; 
};
</pre></blockquote>
<p>
because it imposes <code>CopyInsertable</code> requirements that end up being equivalent to the <code>CopyConstructible</code>
requirements for the default allocator.
<p/>
Technically a library can solve these issues: For special member functions by defining them in some base class, for others
by transforming them effectively into a function template due to the great feature of default template arguments for
function templates (At the very moment the validity of the latter approach depends on a resolution of core language issue
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1635">CWG 1635</a>, though). E.g. the here mentioned 
<code>resize</code> functions of <code>std::vector</code> could be prevented from instantiation by defining them like this 
with an implementation:
</p>
<blockquote><pre>
template&lt;class = void&gt;
void resize(size_type sz) { [&hellip;] }
template&lt;class = void&gt;
void resize(size_type sz, const T&amp; c) { [&hellip;] }
</pre></blockquote>
<p>
In this case, these functions could also be defined in a base class, but the latter approach won't work in all cases.
<p/>
Basically such an implementation is required to constrain all member functions that are not covered by the general
requirements imposed on the actual library template parameters. I tested three different C++11 library implementations
and but none could instantiate for example <code>std::list</code>, <code>std::vector</code>, or <code>std::deque</code> with
value types that are not <code>DefaultConstructible</code> or only <code>MoveConstructible</code>. 
<p/>

<p/>
This issue is raised to clarify the current situation in regard to the actual requirements imposed on user-provided
types that are used to explicitly instantiate Library-provided templates. For example, the current Container requirements
impose very little requirements on the actual value type and it is unclear to which extend library implementations have
to respect that. 
<p/>
The minimum solution of this issue should be to at least realize that there is no fundamental requirement on 
<code>DefaultConstructible</code> for value types of library containers, because we have since C++03 the general
statement of 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> ("In general, a default constructor is not required.").
It is unclear whether <code>CopyConstructible</code> should be required for an explicit instantiation request, but
given the careful introduction of move operations in the library it would seem astonishing that a
<code>MoveConstructible</code> type wouldn't suffice for value types of the container types.
<p/>
In any case I can envision at least two approaches to solve this issue:
</p>
<ol>
<li>
<p>
As indicated in LWG <a href="lwg-defects.html#2292" title="Find a better phrasing for &quot;shall not participate in overload resolution&quot; (Status: Resolved)">2292</a><sup><a href="https://cplusplus.github.io/LWG/issue2292" title="Latest snapshot">(i)</a></sup>, those function could get an explicit "<i>Template Constraints:</i>"
element, albeit this promises more than needed to solve this issue.
</p>
</li>
<li>
<p>
The library could introduce a completely new element form, such as "<i>Instantiation Constraints:</i>" that
would handle this situation for explicit instantiation situations. This would allow for simpler techniques
to solve the issue when explicit instantiation is required compared to the first bullet, because it would not 
(necessarily) guarantee SFINAE-friendly expression-wellformedness, such as inspecting the expression 
<code>std::declval&lt;std::vector&lt;ND&gt;&amp;&gt;.resize(0)</code> in an unevaluated context.
</p>
</li>
</ol>

<p>
It should be noted that the 2013-08-27 comment to LWG <a href="lwg-defects.html#2193" title="Default constructors for standard library containers are explicit (Status: C++14)">2193</a><sup><a href="https://cplusplus.github.io/LWG/issue2193" title="Latest snapshot">(i)</a></sup> could be resolved by a similar solution
as indicated in this issue here.
</p>


<p id="res-2303"><b>Proposed resolution:</b></p>





</body>
</html>
