<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2139: What is a user-defined type?</title>
<meta property="og:title" content="Issue 2139: What is a user-defined type?">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2139.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="2139"><a href="lwg-defects.html#2139">2139</a>. What is a <em>user-defined</em> type?</h3>
<p><b>Section:</b> 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a>, 19.5 <a href="https://wg21.link/syserr">[syserr]</a>, 20.2.8.1 <a href="https://wg21.link/allocator.uses.trait">[allocator.uses.trait]</a>, 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a>, 22.10.15.3 <a href="https://wg21.link/func.bind.isplace">[func.bind.isplace]</a>, 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a>, 21.3.9.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a>, 28.3.3.1 <a href="https://wg21.link/locale">[locale]</a>, 28.3.4.2.5 <a href="https://wg21.link/locale.codecvt">[locale.codecvt]</a>, 28.6.11.1.5 <a href="https://wg21.link/re.regiter.incr">[re.regiter.incr]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Lo&iuml;c Joly <b>Opened:</b> 2012-03-08 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>4
</p>
<p><b>View other</b> <a href="lwg-index-open.html#namespace.std">active issues</a> in [namespace.std].</p>
<p><b>View all other</b> <a href="lwg-index.html#namespace.std">issues</a> in [namespace.std].</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>
The expression "user-defined type" is used in several places in the standard, but I'm not sure what 
it means. More specifically, is a type defined in the standard library a user-defined type?
<p/>
From my understanding of English, it is not. From most of the uses of this term in the standard, it 
seem to be considered as user defined. In some places, I'm hesitant, e.g. 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> p1:
</p>
<blockquote><p>
A program may add a template specialization for any standard library template to namespace <code>std</code> 
only if the declaration depends on a user-defined type and the specialization meets the standard library 
requirements for the original template and is not explicitly prohibited.
</p></blockquote>
<p>
Does it mean we are allowed to add in the namespace <code>std</code> a specialization for 
<code>std::vector&lt;std::pair&lt;T, U&gt;&gt;</code>, for instance?
<p/>
Additional remarks from the reflector discussion: The traditional meaning of user-defined types refers
to class types and enum types, but the library actually means here user-defined types that are not
(purely) library-provided. Presumably a new term - like <em>user-provided type</em> - should be introduced
and properly defined.
</p>

<p><i>[
2012-10 Portland: Move to Deferred 
]</i></p>


<p>
The issue is real, in that we never define this term and rely on a "know it when I see it"
intuition.  However, there is a fear that any attempt to pin down a definition is more
likely to introduce bugs than solve them - getting the wording for this precisely correct
is likely far more work than we are able to give it.
</p>

<p>
There is unease at simple closing as NAD, but not real enthusiasm to provide wording either.
Move to Deferred as we are not opposed to some motivated individual coming back with full
wording to review, but do not want to go out of our way to encourage someone to work on this
in preference to other issues.
</p>

<p><i>[2014-02-20 Re-open Deferred issues as Priority 4]</i></p>


<p><i>[2015-03-05 Jonathan suggests wording]</i></p>

<p>
I dislike the suggestion to change to "user-provided" type because I already find the 
difference between user-declared / user-provided confusing for special member functions, 
so I think it would be better to use a completely different term. The core language
uses "user-defined conversion sequence" and "user-defined literal" and
similar terms for things which the library provides, so I think we
should not refer to "user" at all to distinguish entities defined
outside the implementation from things provided by the implementation.
<p/>
I propose "program-defined type" (and "program-defined specialization"), defined below. 
The P/R below demonstrates the scope of the changes required, even if this name isn't adopted. 
I haven't proposed a change for "User-defined facets" in [locale].
</p>

<p><i>[Lenexa 2015-05-06]</i></p>

<p>RS, HT: The core language uses "user-defined" in a specific way, including library things but excluding core language things, let's use a different term.</p>
<p>MC: Agree.</p>
<p>RS: "which" should be "that", x2</p>
<p>RS: Is std::vector&lt;MyType&gt; a "program-defined type"?</p>
<p>MC: I think it should be.</p>
<p>TK: std::vector&lt;int&gt; seems to take the same path.</p>
<p>JW: std::vector&lt;MyType&gt; isn't program-defined, we don't need it to be, anything that depends on that also depends on =MyType.</p>
<p>TK: The type defined by an "explicit template specialization" should be a program-defined type.</p>
<p>RS: An implicit instantiation of a "program-defined partial specialization" should also be a program-defined type.</p>
<p>JY: This definition formatting is horrible and ugly, can we do better?</p>
<p>RS: Checking ISO directives.</p>
<p>RS: Define "program-defined type" and "program-defined specialization" instead, to get rid of the angle brackets.</p>
<p>JW redrafting.</p>

<p><i>[2017-09-12]</i></p>


<p>Jonathan revises wording as per Lenexa discussion</p>

<strong>Previous resolution [SUPERSEDED]:</strong>

<blockquote class="note">
<p>This wording is relative to N4296.</p>

<ol>
<li><p>Add a new sub-clause to  [definitions]:</p>

<p><ins><b>17.3.? [defns.program.defined]</b></ins></p>
<p>
<ins><b>program-defined</b></ins>
<p/>
<ins>&lt;type&gt; a class type or enumeration type which is not part of the C++
standard library and not defined by the implementation. [<i>Note</i>: Types
defined by the implementation include extensions (4.1 <a href="https://wg21.link/intro.compliance">[intro.compliance]</a>)
and internal types used by the library. &mdash; <i>end note</i>]</ins>
</p>
<p>
<ins><b>program-defined</b></ins>
<p/>
<ins>&lt;specialization&gt; an explicit template specialization or partial
specialization which is not part of the C++ standard library and not
defined by the implementation.</ins>
</p>
</li>

<li><p>Change 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> paragraph 1+2:</p>

<p>
-1- The behavior of a C++ program is undefined if it adds declarations or definitions to namespace <code>std</code> or to a
namespace within namespace <code>std</code> unless otherwise specified. A program may add a template specialization
for any standard library template to namespace <code>std</code> only if the declaration depends on a 
<del>user</del><ins>program</ins>-defined type and the specialization meets the standard library requirements for the 
original template and is not explicitly prohibited.
<p/>
-2- The behavior of a C++ program is undefined if it declares
<p/>
[&hellip;]
<p/>
A program may explicitly instantiate a template defined in the standard library only if the declaration
depends on the name of a <del>user</del><ins>program</ins>-defined type and the instantiation meets the standard 
library requirements for the original template.
</p>
</li>

<li><p>Change 19.5 <a href="https://wg21.link/syserr">[syserr]</a> paragraph 4:</p>

<p>
-4- The <code>is_error_code_enum</code> and <code>is_error_condition_enum</code> may be specialized for 
<del>user</del><ins>program</ins>-defined types to indicate that such types are eligible for class <code>error_code</code> 
and class <code>error_condition</code> automatic conversions, respectively.
</p>
</li>

<li><p>Change 20.2.8.1 <a href="https://wg21.link/allocator.uses.trait">[allocator.uses.trait]</a> paragraph 1:</p>

<p>
-1- <i>Remarks</i>: automatically detects [&hellip;]. A program may specialize this template to derive from 
<code>true_type</code> for a <del>user</del><ins>program</ins>-defined type <code>T</code> that does not have a nested 
<code>allocator_type</code> but nonetheless can be constructed with an allocator where either: [&hellip;]
</p>
</li>

<li><p>Change 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> paragraph 2:</p>

<p>
-2- Instantiations of the <code>is_bind_expression</code> template [&hellip;]. A program may specialize
this template for a <del>user</del><ins>program</ins>-defined type <code>T</code> to have a <code>BaseCharacteristic</code> 
of <code>true_type</code> to indicate that <code>T</code> should be treated as a subexpression in a <code>bind</code> call.
</p>
</li>

<li><p>Change 22.10.15.3 <a href="https://wg21.link/func.bind.isplace">[func.bind.isplace]</a> paragraph 2:</p>

<p>
-2- Instantiations of the <code>is_placeholder</code> template [&hellip;]. A program may specialize this template for a 
<del>user</del><ins>program</ins>-defined type <code>T</code> to have a <code>BaseCharacteristic</code> of 
<code>integral_constant&lt;int, <i>N</i>&gt;</code> with <code><i>N</i> &gt; 0</code> to indicate that <code>T</code> should be 
treated as a placeholder type.
</p>
</li>

<li><p>Change 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a> paragraph 1:</p>

<p>
The unordered associative containers defined in 23.5 use specializations of the class template <code>hash</code> [&hellip;], 
the instantiation <code>hash&lt;Key&gt;</code> shall:
</p>
<ul>
<li><p>[&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>satisfy the requirement that the expression <code>h(k)</code>, where <code>h</code> is an object of type 
<code>hash&lt;Key&gt;</code> and <code>k</code> is an object of type <code>Key</code>, shall not throw an exception unless 
<code>hash&lt;Key&gt;</code> is a <del>user</del><ins>program</ins>-defined specialization that depends on at least one 
<del>user</del><ins>program</ins>-defined type.</p></li>
</ul>
</li>

<li><p>Change 21.3.9.6 <a href="https://wg21.link/meta.trans.ptr">[meta.trans.ptr]</a> Table 57 (<code>common_type</code> row):</p>

<blockquote>
<table border="1">
<caption>Table 57 &mdash; Other transformations</caption>
<tr>
<th align="center">Template</th>
<th align="center">Condition</th>
<th align="center">Comments</th>
</tr>

<tr>
<td colspan="3" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>template &lt;class... T&gt;<br/>
struct common_type;</code>
</td>

<td align="center">
&nbsp;
</td>

<td>
The member typedef <code>type</code> shall be<br/>
defined or omitted as specified below.<br/>
[&hellip;]. A program may<br/>
specialize this trait if at least one<br/>
template parameter in the<br/>
specialization is a <del>user</del><ins>program</ins>-defined type.<br/>
[&hellip;]
</td>
</tr>

<tr>
<td colspan="3" align="center">
<code>&hellip;</code>
</td>
</tr>

</table>
</blockquote>

</li>

<li><p>Change 28.3.4.2.5 <a href="https://wg21.link/locale.codecvt">[locale.codecvt]</a> paragraph 3:</p>

<p>
-3- The specializations required in Table 81 (22.3.1.1.1) [&hellip;]. Other encodings can be converted 
by specializing on a <del>user</del><ins>program</ins>-defined <code>stateT</code> type.[&hellip;]
</p>
</li>

<li><p>Change 28.6.11.1.5 <a href="https://wg21.link/re.regiter.incr">[re.regiter.incr]</a> paragraph 8:</p>

<p>
-8- [<i>Note</i>: This means that a compiler may call an implementation-specific search function, in which case
a <del>user</del><ins>program</ins>-defined specialization of <code>regex_search</code> will not be called. &mdash; 
<i>end note</i>]
</p>
</li>
</ol>
</blockquote>

<p><i>[2018-3-14 Wednesday evening issues processing; move to Ready]</i></p>

<p>After this lands, we need to audit Annex C to find "user-defined type" Example: [diff.cpp03.containers]/3</p>

<p><i>[2018-06 Rapperswil: Adopted]</i></p>



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

<ol>
<li><p>Add a new sub-clause to  [definitions]:</p>

<p><ins><b>20.3.? [defns.program.defined.spec]</b></ins></p>
<p>
<ins><b>program-defined specialization</b></ins>
<p/>
<ins>explicit template specialization or partial
specialization that is not part of the C++ standard library and not
defined by the implementation</ins>
</p>
<p><ins><b>20.3.? [defns.program.defined.type]</b></ins></p>
<p>
<ins><b>program-defined type</b></ins>
<p/>
<ins>class type or enumeration type that is not part of the C++
standard library and not defined by the implementation,
or an instantiation of a program-defined specialization</ins>
</p>
<blockquote class="note">
[<i>Drafting note:</i> ISO directives say the following Note should be labelled as a "Note to entry"
but the C++ WP doesn't follow that rule (yet). &mdash; <i>end drafting note</i>]
</blockquote>
<p><ins> [<i>Note</i>: Types
defined by the implementation include extensions (4.1 <a href="https://wg21.link/intro.compliance">[intro.compliance]</a>)
and internal types used by the library. &mdash; <i>end note</i>]</ins>
</p>
</li>

<li><p>Change 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> paragraph 1+2:</p>

<p>
-1- The behavior of a C++ program is undefined if it adds declarations or definitions to namespace <code>std</code> or to a
namespace within namespace <code>std</code> unless otherwise specified. A program may add a template specialization
for any standard library template to namespace <code>std</code> only if the declaration depends on a 
<del>user</del><ins>program</ins>-defined type and the specialization meets the standard library requirements for the 
original template and is not explicitly prohibited.
<p/>
-2- The behavior of a C++ program is undefined if it declares
<p/>
[&hellip;]
<p/>
A program may explicitly instantiate a template defined in the standard library only if the declaration
depends on the name of a <del>user</del><ins>program</ins>-defined type and the instantiation meets the standard 
library requirements for the original template.
</p>
</li>

<li><p>Change 19.5 <a href="https://wg21.link/syserr">[syserr]</a> paragraph 4:</p>

<p>
-4- The <code>is_error_code_enum</code> and <code>is_error_condition_enum</code> may be specialized for 
<del>user</del><ins>program</ins>-defined types to indicate that such types are eligible for class <code>error_code</code> 
and class <code>error_condition</code> automatic conversions, respectively.
</p>
</li>

<li><p>Change 20.2.8.1 <a href="https://wg21.link/allocator.uses.trait">[allocator.uses.trait]</a> paragraph 1:</p>

<p>
-1- <i>Remarks</i>: automatically detects [&hellip;]. A program may specialize this template to derive from 
<code>true_type</code> for a <del>user</del><ins>program</ins>-defined type <code>T</code> that does not have a nested 
<code>allocator_type</code> but nonetheless can be constructed with an allocator where either: [&hellip;]
</p>
</li>

<li><p>Change 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> paragraph 2:</p>

<p>
-2- Instantiations of the <code>is_bind_expression</code> template [&hellip;]. A program may specialize
this template for a <del>user</del><ins>program</ins>-defined type <code>T</code> to have a <code>BaseCharacteristic</code> 
of <code>true_type</code> to indicate that <code>T</code> should be treated as a subexpression in a <code>bind</code> call.
</p>
</li>

<li><p>Change 22.10.15.3 <a href="https://wg21.link/func.bind.isplace">[func.bind.isplace]</a> paragraph 2:</p>

<p>
-2- Instantiations of the <code>is_placeholder</code> template [&hellip;]. A program may specialize this template for a 
<del>user</del><ins>program</ins>-defined type <code>T</code> to have a <code>BaseCharacteristic</code> of 
<code>integral_constant&lt;int, <i>N</i>&gt;</code> with <code><i>N</i> &gt; 0</code> to indicate that <code>T</code> should be 
treated as a placeholder type.
</p>
</li>

<li><p>Change 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a> paragraph 1:</p>

<p>
The unordered associative containers defined in 23.5 use specializations of the class template <code>hash</code> [&hellip;], 
the instantiation <code>hash&lt;Key&gt;</code> shall:
</p>
<ul>
<li><p>[&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>satisfy the requirement that the expression <code>h(k)</code>, where <code>h</code> is an object of type 
<code>hash&lt;Key&gt;</code> and <code>k</code> is an object of type <code>Key</code>, shall not throw an exception unless 
<code>hash&lt;Key&gt;</code> is a <del>user</del><ins>program</ins>-defined specialization that depends on at least one 
<del>user</del><ins>program</ins>-defined type.</p></li>
</ul>
</li>

<li><p>Change 21.3.9.6 <a href="https://wg21.link/meta.trans.ptr">[meta.trans.ptr]</a> Table 57 (<code>common_type</code> row):</p>

<blockquote>
<table border="1">
<caption>Table 57 &mdash; Other transformations</caption>
<tr>
<th align="center">Template</th>
<th align="center">Condition</th>
<th align="center">Comments</th>
</tr>

<tr>
<td colspan="3" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>template &lt;class... T&gt;<br/>
struct common_type;</code>
</td>

<td align="center">
&nbsp;
</td>

<td>
The member typedef <code>type</code> shall be<br/>
defined or omitted as specified below.<br/>
[&hellip;]. A program may<br/>
specialize this trait if at least one<br/>
template parameter in the<br/>
specialization is a <del>user</del><ins>program</ins>-defined type.<br/>
[&hellip;]
</td>
</tr>

<tr>
<td colspan="3" align="center">
<code>&hellip;</code>
</td>
</tr>

</table>
</blockquote>

</li>

<li><p>Change 28.3.4.2.5 <a href="https://wg21.link/locale.codecvt">[locale.codecvt]</a> paragraph 3:</p>

<p>
-3- The specializations required in Table 81 (22.3.1.1.1) [&hellip;]. Other encodings can be converted 
by specializing on a <del>user</del><ins>program</ins>-defined <code>stateT</code> type.[&hellip;]
</p>
</li>

<li><p>Change 28.6.11.1.5 <a href="https://wg21.link/re.regiter.incr">[re.regiter.incr]</a> paragraph 8:</p>

<p>
-8- [<i>Note</i>: This means that a compiler may call an implementation-specific search function, in which case
a <del>user</del><ins>program</ins>-defined specialization of <code>regex_search</code> will not be called. &mdash; 
<i>end note</i>]
</p>
</li>
</ol>





</body>
</html>
