<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2010: is_* traits for binding operations can't be meaningfully specialized</title>
<meta property="og:title" content="Issue 2010: is_* traits for binding operations can't be meaningfully specialized">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2010.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++14">C++14</a> status.</em></p>
<h3 id="2010"><a href="lwg-defects.html#2010">2010</a>. <code>is_* traits</code> for binding operations can't be meaningfully specialized</h3>
<p><b>Section:</b> 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Sean Hunt <b>Opened:</b> 2010-07-19 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#func.bind.isbind">issues</a> in [func.bind.isbind].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>
<p>
22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> says for <code>is_bind_expression</code>:
</p>

<blockquote><p>
Users may specialize this template to indicate that a type should be
treated as a subexpression in a <code>bind</code> call.
</p></blockquote>

<p>
But it also says:
</p>

<blockquote><p>
If <code>T</code> is a type returned from <code>bind</code>,
<code>is_bind_expression&lt;T&gt;</code> shall be publicly derived from
<code>integral_constant&lt;bool, true&gt;</code>, otherwise from
<code>integral_constant&lt;bool, false&gt;</code>.
</p></blockquote>

<p>
This means that while the user is free to specialize, any specialization
would have to be <code>false</code> to avoid violating the second
requirement. A similar problem exists for <code>is_placeholder</code>.
</p>

<p><i>[
2010 Batavia (post meeting session)
]</i></p>

<p>
Alisdair recognises this is clearly a bug introduced by some wording he
wrote, the sole purpose of this metafunction is as a customization point
for users to write their own <code>bind</code>-expression types that participate
in the standard library <code>bind</code> protocol.  The consensus was that this
should be fixed in Madrid, moved to Open.
</p>

<p><i>[2011-05-13 Jonathan Wakely comments and provides proposed wording]</i></p>


<p>
The requirements are that <code>is_bind_expression&lt;T&gt;::value</code> is true when <code>T</code>
is a type returned from <code>bind</code>, false for any other type, except when
there's a specialization involving a user-defined type (N.B. 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> 
means we don't need to say e.g. <code>is_bind_expression&lt;string&gt;</code> is false.)
<p/>
The obvious way to meet the requirements is for the primary template
to derive from <code>integral_constant&lt;bool, false&gt;</code> and for implementations
to provide specializations for the unspecified types returned from
<code>bind</code>.  User-defined specializations can do whatever they like, as long
as <code>is_bind_expression::value</code> is sane. There's no reason to forbid
users from defining <code>is_bind_expression&lt;<i>user_defined_type</i>&gt;::value=false</code>
if that's what they want to do.
<p/>
Similar reasoning applies to <code>is_placeholder</code>, but a further issue is
that 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> contains wording for <code>is_placeholder</code> but
contains no definition of it and the sub-clause name only refers to
<code>is_bind_expression</code>. The wording below proposes splitting paragraphs 3
and 4 of 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> into a new sub-clause covering
<code>is_placeholder</code>.
<p/>
If the template specializations added by the proposed wording are too
vague then they could be preceded by "for exposition only" comments
</p>

<p><i>[2011-05-18 Daniel comments and provides some refinements to the P&#47;R]</i></p>


<p>
Both <code>bind</code>-related type traits should take advantage of the
UnaryTypeTrait requirements. Additionally, the updated wording does not
imply that the implementation provides several specializations. Wording was 
used similar to the specification of the <code>uses_allocator</code> type trait 
(which unfortunately is not expressed in terms of BinaryTypeTrait requirements).
</p>

<p><i>[Bloomington, 2011]</i></p>

<p>
Move to Ready
</p>



<p id="res-2010"><b>Proposed resolution:</b></p>
<p>This wording is relative to the FDIS.</p>
<ol>
<li><p>Change 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a> to:</p>

<blockquote><pre>
namespace std {
  template&lt;class T&gt; struct is_bind_expression<ins>; <i>// see below</i></ins>
    <del>: integral_constant&lt;bool, <i>see below</i>&gt; { };</del>
}
</pre><blockquote><p>
-1- <code>is_bind_expression</code> can be used to detect function objects generated by <code>bind</code>. <code>bind</code> 
uses <code>is_bind_expression</code> to detect subexpressions. <del>Users may specialize this template to indicate 
that a type should be treated as a subexpression in a <code>bind</code> call.</del>
<p/>
-2- <del>If <code>T</code> is a type returned from <code>bind</code>, <code>is_bind_expression&lt;T&gt;</code> shall 
be publicly derived from <code>integral_constant&lt;bool, true&gt;</code>, otherwise from 
<code>integral_constant&lt;bool, false&gt;</code></del><ins>Instantiations of the <code>is_bind_expression</code> template
shall meet the UnaryTypeTrait requirements ([meta.rqmts]). The implementation shall provide a definition
that has a BaseCharacteristic of <code>true_type</code> if <code>T</code> is a type returned from <code>bind</code>, otherwise 
it shall have a BaseCharacteristic of <code>false_type</code>. A program may specialize this template for a user-defined 
type <code>T</code> to have a BaseCharacteristic of <code>true_type</code> to indicate that <code>T</code> should be treated 
as a subexpression in a <code>bind</code> call.</ins>.
<p/>
<del>-3- <code>is_placeholder</code> can be used to detect the standard placeholders <code>_1</code>, <code>_2</code>, and so on. 
<code>bind</code> uses <code>is_placeholder</code> to detect placeholders. Users may specialize this template to indicate 
a placeholder type.</del>
<p/>
<del>-4- If <code>T</code> is the type of <code>std::placeholders::_J</code>, <code>is_placeholder&lt;T&gt;</code> shall be 
publicly derived from <code>integral_constant&lt;int, J&gt;</code>, otherwise from <code>integral_constant&lt;int, 0&gt;</code>.</del>
</p></blockquote></blockquote>
</li>
<li><p>Insert a new sub-clause immediately following sub-clause 22.10.15.2 <a href="https://wg21.link/func.bind.isbind">[func.bind.isbind]</a>, the suggested
sub-clause tag is [func.bind.isplace]:
</p>
<h3><ins>20.8.9.1.?  Class template <code>is_placeholder</code>  [func.bind.isplace]</ins></h3> 
<blockquote><pre>
<ins>namespace std {
  template&lt;class T&gt; struct is_placeholder; <i>// see below</i>
}</ins>
</pre><blockquote><p>
<ins>-?- <code>is_placeholder</code> can be used to detect the standard placeholders <code>_1</code>, <code>_2</code>, and so on. 
<code>bind</code> uses <code>is_placeholder</code> to detect placeholders.</ins>
<p/>
<ins>-?- Instantiations of the <code>is_placeholder</code> template shall meet the UnaryTypeTrait requirements ([meta.rqmts]). 
The implementation shall provide a definition that has a BaseCharacteristic of <code>integral_constant&lt;int, J&gt;</code> 
if <code>T</code> is the type of <code>std::placeholders::_J</code>, otherwise it shall have a BaseCharacteristic of 
<code>integral_constant&lt;int, 0&gt;</code>. A program may specialize this template for a user-defined type <code>T</code> 
to have a BaseCharacteristic 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.</ins>
</p></blockquote></blockquote>
</li>
</ol>





</body>
</html>
