<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2149: Concerns about 20.8/5</title>
<meta property="og:title" content="Issue 2149: Concerns about 20.8/5">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2149.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="2149"><a href="lwg-defects.html#2149">2149</a>. Concerns about 20.8/5</h3>
<p><b>Section:</b> 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Scott Meyers <b>Opened:</b> 2012-02-15 <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#function.objects">issues</a> in [function.objects].</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 <a href="https://wg21.link/function.objects">[function.objects]</a> p5 says:
</p>
<blockquote><p>
To enable adaptors and other components to manipulate function objects that take one or two arguments
it is required that the function objects correspondingly provide typedefs <code>argument_type</code> and 
<code>result_type</code> for function objects that take one argument and <code>first_argument_type</code>, 
<code>second_argument_type</code>, and <code>result_type</code> for function objects that take two arguments.
</p></blockquote>
<p>
I have two concerns about this paragraph.  First, the wording appears to prescribe a requirement for all 
function objects in valid C++ programs, but it seems unlikely that that is the intent.  As such, the scope 
of the requirement is unclear.  For example, there is no mention of these typedefs in the specification for 
closures (5.1.2), and Daniel Kr&uuml;gler has explained in the thread at 
<a href="http://tinyurl.com/856plkn">http://tinyurl.com/856plkn</a> that conforming implementations can 
detect the difference between closures with and without these typedefs.  (Neither gcc 4.6 nor VC10 appear 
to define typedefs such as <code>result_type</code> for closure types. I have not tested other compilers.)
<p/>
Second, the requirement appears to be unimplementable in some cases, notably for function objects returned 
from <code>std::bind</code>, as Howard Hinnant explains in the thread at <a href="http://tinyurl.com/6q5bos4">http://tinyurl.com/6q5bos4</a>.
<p/>
From what I can tell, the standard already defines which adaptability typedefs must be provided by various 
kinds of function objects in the specifications for those objects.  Examples include the function objects 
specified in 22.10.6 <a href="https://wg21.link/refwrap">[refwrap]</a>- [negators]. I therefore suggest that 
22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>&#47;5 simply be removed from the standard. I don't think it adds anything 
except opportunities for confusion.
</p>

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

<p>
This wording caused confusion earlier in the week when reviewing Stefan's paper on <code>greater&lt;></code>.
</p>

<p>
This phrasing sounds normative, but is actually descriptive but uses unfortunate wording.
</p>

<p>
The main reason this wording exists is to document the protocol required to support the legacy binders
in Annex D.
</p>

<p>
Stefan points out that <code>unary_negate</code> and <code>binary_negate</code> have not been deprecated and rely
on this.  He plans a paper to remove this dependency.
</p>

<p>
Consensus that this wording is inadequate, confusing, and probably should be removed.  However, that
leaves a big hole in the specification for the legacy binders, that needs filling.
</p>

<p>
While not opposed to striking this paragraph, we will need the additional wording to fix the openning
hole before this issue can move forward.
</p>

<p><i>[
2013-04-14 STL provides rationale
]</i></p>


<p>Rationale:</p>

<p>I've concluded that Scott's original proposed resolution was correct and complete. There are two sides to this 
story: the producers and the consumers of these typedefs.</p>

<p><em>Producers</em>: As Scott noted, the Standard clearly documents which function objects must provide these 
typedefs. Some function objects must provide them unconditionally (e.g. <code>plus&lt;T&gt;</code> (for <code>T != void</code>), 
22.10.7 <a href="https://wg21.link/arithmetic.operations">[arithmetic.operations]</a>/1), some conditionally (e.g. <code>reference_wrapper&lt;T&gt;</code>, 
22.10.6 <a href="https://wg21.link/refwrap">[refwrap]</a>/2-4), and some don't have to provide them at all (e.g. lambdas, 7.5.6 <a href="https://wg21.link/expr.prim.lambda">[expr.prim.lambda]</a>). 
These requirements are clear, so we shouldn't change them or even add informative notes. Furthermore, because these 
typedefs aren't needed in the C++11 world with <code>decltype</code>/perfect forwarding/etc., we shouldn't add more 
requirements to provide them.</p>

<p><em>Consumers</em>: This is what we were concerned about at Portland. However, the consumers also clearly document 
their requirements in the existing text. For example, <code>reference_wrapper&lt;T&gt;</code> is also a conditional consumer, 
and 22.10.6 <a href="https://wg21.link/refwrap">[refwrap]</a> explains what typedefs it's looking for. We were especially concerned about the old negators 
and the deprecated binders, but they're okay too.  [negators] clearly says that 
<code>unary_negate&lt;Predicate&gt;</code> requires <code>Predicate::argument_type</code> to be a type, and 
<code>binary_negate&lt;Predicate&gt;</code> requires <code>Predicate::first_argument_type</code> and <code>Predicate::second_argument_type</code> 
to be types. (<code>unary_negate</code>/<code>binary_negate</code> provide <code>result_type</code> but they don't consume it.) 
99 [depr.lib.binders] behaves the same way with <code>Fn::first_argument_type</code>, <code>Fn::second_argument_type</code>, 
and <code>Fn::result_type</code>. No additional wording is necessary.</p>

<p>A careful reading of 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>/5 reveals that it wasn't talking about anything beyond the mere 
existence of the mentioned typedefs &mdash; for example, it didn't mention that the function object's return type should be 
<code>result_type</code>, or even convertible to <code>result_type</code>. As the producers and consumers are certainly talking about 
the existence of the typedefs (in addition to clearly implying semantic requirements), we lose nothing by deleting the 
unnecessary paragraph.</p>

<p><i>[2013-04-18, Bristol]</i></p>


<p>Previous wording:</p>

<blockquote class="note"> 
<p>Remove 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a> p5:</p>

<blockquote><p><del>
To enable adaptors and other components to manipulate function objects that take one or two arguments
it is required that the function objects correspondingly provide typedefs <code>argument_type</code> and 
<code>result_type</code> for function objects that take one argument and <code>first_argument_type</code>, 
<code>second_argument_type</code>, and <code>result_type</code> for function objects that take two arguments.
</del></p></blockquote>
</blockquote>



<p id="res-2149"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf">N3485</a>.</p>

<p>Edit 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a> p5:</p>

<blockquote><p>
<ins>[<i>Note:</i></ins>To enable adaptors and other components to manipulate function objects that take one or two arguments
<del>it is required that the function objects</del><ins>many of the function objects in this clause</ins> correspondingly provide 
typedefs <code>argument_type</code> and <code>result_type</code> for function objects that take one argument and <code>first_argument_type</code>, 
<code>second_argument_type</code>, and <code>result_type</code> for function objects that take two arguments.<ins>&mdash; <i>end note</i>]</ins>
</p></blockquote>





</body>
</html>
