<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2290: Top-level "SFINAE"-based constraints should get a separate definition in Clause 17</title>
<meta property="og:title" content="Issue 2290: Top-level &quot;SFINAE&quot;-based constraints should get a separate definition in Clause 17">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2290.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#Open">Open</a> status.</em></p>
<h3 id="2290"><a href="lwg-active.html#2290">2290</a>. Top-level "SFINAE"-based constraints should get a separate definition in Clause 17</h3>
<p><b>Section:</b> 21 <a href="https://wg21.link/meta">[meta]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2013-09-02 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#meta">active issues</a> in [meta].</p>
<p><b>View all other</b> <a href="lwg-index.html#meta">issues</a> in [meta].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The current library specification uses at several places wording that is intended to refer to
core language template deduction failure at the top-level of expressions (aka "SFINAE"), for example:
</p>

<blockquote><p>
The expression <code>declval&lt;T&gt;() = declval&lt;U&gt;()</code> is well-formed when treated as an unevaluated operand (Clause 5). 
Access checking is performed as if in a context unrelated to <code>T</code> and <code>U</code>. Only the validity of the immediate context 
of the assignment expression is considered. [<i>Note:</i> The compilation of the expression can result in side effects 
such as the instantiation of class template specializations and function template specializations, the generation of
implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result in the program
being ill-formed. &mdash; <i>end note</i>]
</p></blockquote>

<p>
Similar wording can be found in the specification of <code>result_of</code>, <code>is_constructible</code>, and <code>is_convertible</code>,
being added to resolve an NB comment by LWG <a href="lwg-defects.html#1390" title="Limit speculative compilation for constructible&#47;convertible traits (Status: Resolved)">1390</a><sup><a href="https://cplusplus.github.io/LWG/issue1390" title="Latest snapshot">(i)</a></sup> and <a href="lwg-defects.html#1391" title="constructible&#47;convertible traits and access control (Status: Resolved)">1391</a><sup><a href="https://cplusplus.github.io/LWG/issue1391" title="Latest snapshot">(i)</a></sup> through 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3142.html">N3142</a>.
<p/>
This wording is necessary to limit speculative compilations needed to implement these traits, but it is also lengthy and repetitive.
</p>

<p><i>[2014-05-19, Daniel suggests a descriptive term]</i></p>

<p>
<b>constrictedly well-formed expression</b>:
<p/>
An expression <em>e</em> depending on a set of types <code>A1</code>, ..., <code>An</code> which is well-formed when treated as 
an unevaluated operand (Clause 5). Access checking is performed as if in a context unrelated to <code>A1</code>, ..., 
<code>An</code>. Only the validity of the immediate context of <em>e</em> is considered. [<i>Note:</i> The compilation of 
the expression can result in side effects such as the instantiation of class template specializations and function 
template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the 
"immediate context" and can result in the program being ill-formed. &mdash; <i>end note</i>]
</p>

<p><i>[2014-05-20, Richard and Jonathan suggest better terms]</i></p>

<p>
Richard suggested "locally well-formed"
<p/>
Jonathan suggested "contextually well-formed" and then "The expression ... is valid in a contrived argument
deduction context"
</p>

<p><i>[2014-06-07, Daniel comments and improves wording]</i></p>

<p>
The 2014-05-19 suggestion did only apply to expressions, but there are two important examples that are not expressions, but instead
are involving an <em>object definition</em> (<code>std::is_constructible</code>) and a <em>function definition</em> 
(<code>std::is_convertible</code>), respectively, instead. Therefore I suggest to rephrase the usage of "expression" into "program 
construct" in the definition of Jonathan's suggestion of "valid in a contrived argument deduction context".
<p/>
I would like to point out that given the new definition of "valid in a contrived argument deduction context", there are several other 
places of the Library specification that could take advantage of this wording to improve the existing specification, such as 
22.10.17.3 <a href="https://wg21.link/func.wrap.func">[func.wrap.func]</a> p2, most functions in 20.2.9.3 <a href="https://wg21.link/allocator.traits.members">[allocator.traits.members]</a>, and the <code>**Insertable</code>, 
<code>EmplaceConstructible</code>, and <code>Erasable</code> definitions in 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a>, but given that
these are not fully described in terms of the aforementioned wording <em>yet</em>, I would recommend to fix them by a separate issue 
once the committee has agreed on following the suggestion presented by this issue.
</p>

<p><i>[2015-05-05 Lenexa: Move to Open]</i></p>

<p>...</p>
<p>MC: I think we like the direction but it isn't quite right: it needs some work</p>
<p>JW: I'm prepared to volunteer to move that further, hopefully with the help of Daniel</p>
<p>Roger Orr: should this be Core wording because it doesn't really have anything to do with libraries - the term could then just be used here</p>
<p>AM: Core has nothing to deal with that, though</p>
<p>HT: it seems there is nothing to imply that allows dropping out with an error - maybe that's a separate issue</p>
<p>MC: I'm not getting what you are getting at: could you write an issue? - any objection to move to Open?</p>
<p>...</p>


<p id="res-2290"><b>Proposed resolution:</b></p>
<p>This wording is relative to N3936.</p>

<ol>
<li><p>Add the following new definition to  [definitions] as indicated:</p>

<p>
<ins><b>valid in a contrived argument deduction context</b> [defns.valid.contr.context]</ins>
<p/>
<ins>A program construct <em>c</em> depending on a set of types <code>A1</code>, ..., <code>An</code>, and treated as 
an unevaluated operand (Clause 5) when <em>c</em> is an expression, which is well-formed. 
Access checking is performed as if in a context unrelated to <code>A1</code>, ..., <code>An</code>. 
Only the validity of the immediate context (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>) of <em>c</em> is considered. 
[<i>Note:</i> The compilation of <em>c</em> can result in side effects such as the instantiation of class template 
specializations and function template specializations, the generation of implicitly-defined functions, and so on. 
Such side effects are not in the "immediate context" and can result in the program being ill-formed. &mdash; 
<i>end note</i>].</ins>
</p>
</li>

<li><p>Change Table 49 ("Type property predicates") as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 49 &mdash; Type property predicates</caption>
<tr>
<th align="center">Template</th>
<th align="center">Condition</th>
<th align="center">Preconditions</th>
</tr>

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

<tr>
<td>
<code>template &lt;class T, class U&gt;<br/>
struct is_assignable;</code>
</td>

<td>
The expression
<code>declval&lt;T&gt;() =<br/>
declval&lt;U&gt;()</code> is <ins>valid in a<br/>
contrived argument deduction context<br/>
([defns.valid.contr.context]) for types<br/>
<code>T</code> and <code>U</code>.</ins>
<del>well-formed when treated<br/>
as an unevaluated operand<br/>
(Clause 5). Access<br/>
checking is performed as if<br/>
in a context unrelated to <code>T</code><br/>
and <code>U</code>. Only the validity of<br/>
the immediate context of<br/>
the assignment expression<br/>
is considered. [<i>Note</i>: The<br/>
compilation of the<br/>
expression can result in<br/>
side effects such as the<br/>
instantiation of class<br/>
template specializations<br/>
and function template<br/>
specializations, the<br/>
generation of<br/>
implicitly-defined<br/>
functions, and so on. Such<br/>
side effects are not in the<br/>
"immediate context" and<br/>
can result in the program<br/>
being ill-formed. &mdash; end<br/>
note]</del>
</td>

<td align="center">
[&hellip;]
</td>
</tr>

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

</table>
</blockquote>

</li>

<li><p>Change 21.3.6.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a> p7 as indicated:</p>

<blockquote><p>
-7- Given the following function prototype:
</p>
<blockquote><pre>
template &lt;class T&gt;
  add_rvalue_reference_t&lt;T&gt; create() noexcept;
</pre></blockquote>
<p>
the predicate condition for a template specialization <code>is_constructible&lt;T, Args...&gt;</code> shall be satisfied
if and only if the following variable definition <del>would be well-formed</del> for some invented 
variable <code>t</code> <ins>would be valid in a contrived argument deduction context ([defns.valid.contr.context]) for 
types <code>T</code> and <code>Args...</code></ins>:
</p>
<blockquote><pre>
T t(create&lt;Args&gt;()...);
</pre></blockquote>
<p>
[<i>Note</i>: These tokens are never interpreted as a function declaration. &mdash; <i>end note</i>] <del>Access checking is
performed as if in a context unrelated to <code>T</code> and any of the <code>Args</code>. Only the validity of the immediate context
of the variable initialization is considered. [<i>Note</i>: The evaluation of the initialization can result in side
effects such as the instantiation of class template specializations and function template specializations, the
generation of implicitly-defined functions, and so on. Such side effects are not in the "immediate context"
and can result in the program being ill-formed. &mdash; <i>end note</i>]</del>
</p>
</blockquote>
</li>

<li><p>Change Table 57 ("Other transformations") as indicated:</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 Fn, class... ArgTypes&gt;<br/>
struct result_of&lt;Fn(ArgTypes...)&gt;;</code>
</td>

<td align="center">
[&hellip;]
</td>

<td>
If the expression<br/>
<code><i>INVOKE</i>(declval&lt;Fn&gt;(),<br/>
declval&lt;ArgTypes&gt;()...)</code> is<br/>
<ins>valid in a contrived argument deduction<br/>
context ([defns.valid.contr.context]) for types<br/>
<code>Fn</code> and <code>ArgTypes...</code></ins>
<del>well<br/>
formed when treated as an<br/>
unevaluated operand (Clause 5)</del>, the<br/>
member typedef type shall name the<br/>
type<br/>
<code>decltype(<i>INVOKE</i>(declval&lt;Fn&gt;(),<br/>
declval&lt;ArgTypes&gt;()...))</code>;<br/>
otherwise, there shall be no member<br/>
type. <del>Access checking is performed as<br/>
if in a context unrelated to <code>Fn</code> and<br/>
<code>ArgTypes</code>. Only the validity of the<br/>
immediate context of the expression is<br/>
considered. [<i>Note</i>: The compilation of<br/>
the expression can result in side<br/>
effects such as the instantiation of<br/>
class template specializations and<br/>
function template specializations, the<br/>
generation of implicitly-defined<br/>
functions, and so on. Such side effects<br/>
are not in the "immediate context"<br/>
and can result in the program being<br/>
ill-formed. &mdash; <i>end note</i>]</del>
</td>
</tr>

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

</table>
</blockquote>

</li>

<li><p>Change 21.3.8 <a href="https://wg21.link/meta.rel">[meta.rel]</a> p4 as indicated:</p>

<blockquote><p>
-4- Given the following function prototype:
</p>
<blockquote><pre>
template &lt;class T&gt;
  add_rvalue_reference_t&lt;T&gt; create() noexcept;
</pre></blockquote>
<p>
the predicate condition for a template specialization <code>is_convertible&lt;From, To&gt;</code> shall be satisfied if and
only if the return expression in the following code would be <del>well-formed</del><ins>valid in a contrived argument 
deduction context ([defns.valid.contr.context]) for types <code>To</code> and <code>From</code></ins>, including any implicit conversions
to the return type of the function:
</p>
<blockquote><pre>
To test() {
  return create&lt;From&gt;();
}
</pre></blockquote>
<p>
[<i>Note</i>: This requirement gives well defined results for reference types, <code>void</code> types, array types, and
function types. &mdash; <i>end note</i>] <del>Access checking is performed as if in a context unrelated to <code>To</code> 
and <code>From</code>. Only the validity of the immediate context of the expression of the return-statement (including conversions to
the return type) is considered. [<i>Note</i>: The evaluation of the conversion can result in side effects such as
the instantiation of class template specializations and function template specializations, the generation of
implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result
in the program being ill-formed. &mdash; <i>end note</i>]</del>
</p>
</blockquote>
</li>

</ol>





</body>
</html>
