<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1240: Deleted comparison functions of std::function not needed</title>
<meta property="og:title" content="Issue 1240: Deleted comparison functions of std::function not needed">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1240.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++11">C++11</a> status.</em></p>
<h3 id="1240"><a href="lwg-defects.html#1240">1240</a>. Deleted comparison functions of <code>std::function</code> not needed</h3>
<p><b>Section:</b> 22.10.17.3 <a href="https://wg21.link/func.wrap.func">[func.wrap.func]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2009-10-18 <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.wrap.func">issues</a> in [func.wrap.func].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The class template <code>std::function</code> contains the following member
declarations:
</p>

<blockquote><pre>
// deleted overloads close possible hole in the type system
template&lt;class R2, class... ArgTypes2&gt;
  bool operator==(const function&lt;R2(ArgTypes2...)&gt;&amp;) = delete;
template&lt;class R2, class... ArgTypes2&gt;
  bool operator!=(const function&lt;R2(ArgTypes2...)&gt;&amp;) = delete;
</pre></blockquote>

<p>
The leading comment here is part of the history of <code>std::function</code>, which
was introduced with 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1402.html#undefined_operators">N1402</a>.
During that time no explicit conversion functions existed, and the
"safe-bool" idiom (based on pointers-to-member) was a popular
technique. The only disadvantage of this idiom was that given two
objects <code>f1</code> and <code>f2</code> of type <code>std::function</code> the expression
</p>

<blockquote><pre>
f1 == f2;
</pre></blockquote>

<p>
was well-formed, just because the built-in <code>operator==</code> for pointer to member
was considered after a single user-defined conversion. To fix this, an
overload set of <em>undefined</em> comparison functions was added,
such that overload resolution would prefer those ending up in a linkage error.
The new language facility of deleted functions provided a much better
diagnostic mechanism to fix this issue.
</p>

<p>
The central point of this issue is, that with the replacement of the
safe-bool idiom by explicit conversion to bool the original "hole in the
type system" does no longer exist and therefore the comment is wrong and
the superfluous function definitions should be removed as well. An
explicit conversion function is considered in direct-initialization
situations only, which indirectly contain the so-called "contextual
conversion to bool" (7.3 <a href="https://wg21.link/conv">[conv]</a>/3). These conversions are not considered for
<code>==</code> or <code>!=</code> as defined by the core language.
</p>

<p><i>[
Post-Rapperswil
]</i></p>


<blockquote><p>
Moved to Tentatively Ready after 5 positive votes on c++std-lib.
</p></blockquote>

<p><i>[
Adopted at 2010-11 Batavia
]</i></p>




<p id="res-1240"><b>Proposed resolution:</b></p>
<p>
In 22.10.17.3 <a href="https://wg21.link/func.wrap.func">[func.wrap.func]</a>/1, class function change as indicated:
</p>

<blockquote><pre>
// 20.7.15.2.3, function capacity:
explicit operator bool() const;

<del>// deleted overloads close possible hole in the type system</del>
<del>template&lt;class R2, class... ArgTypes2&gt;</del>
  <del>bool operator==(const function&lt;R2(ArgTypes2...)&gt;&amp;) = delete;</del>
<del>template&lt;class R2, class... ArgTypes2&gt;</del>
  <del>bool operator!=(const function&lt;R2(ArgTypes2...)&gt;&amp;) = delete;</del>
</pre></blockquote>





</body>
</html>
