<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 556: Is Compare a BinaryPredicate?</title>
<meta property="og:title" content="Issue 556: Is Compare a BinaryPredicate?">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue556.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="556"><a href="lwg-defects.html#556">556</a>. Is <code>Compare</code> a <code>BinaryPredicate</code>?</h3>
<p><b>Section:</b> 26.8 <a href="https://wg21.link/alg.sorting">[alg.sorting]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2006-02-05 <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#alg.sorting">issues</a> in [alg.sorting].</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>
In 25, p8 we allow BinaryPredicates to return a type that's convertible
to bool but need not actually be bool. That allows predicates to return
things like proxies and requires that implementations be careful about
what kinds of expressions they use the result of the predicate in (e.g.,
the expression in if (!pred(a, b)) need not be well-formed since the
negation operator may be inaccessible or return a type that's not
convertible to bool).
</p>
<p>
Here's the text for reference:
</p>
<blockquote><p>
  ...if an algorithm takes BinaryPredicate binary_pred as its argument
 and first1 and first2 as its iterator arguments, it should work
 correctly in the construct if (binary_pred(*first1, first2)){...}.
</p></blockquote>

<p>
In 25.3, p2 we require that the Compare function object return true
of false, which would seem to preclude such proxies. The relevant text
is here:
</p>
<blockquote><p>
  Compare is used as a function object which returns true if the first
  argument is less than the second, and false otherwise...
</p></blockquote>

<p><i>[
Portland:  Jack to define "convertible to bool" such that short circuiting isn't
destroyed.
]</i></p>


<p><i>[
2009-07-28 Reopened by Alisdair.  No longer solved by concepts.
]</i></p>


<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
Move to Review once wording received. Stefanus to send proposed wording.
</p></blockquote>

<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
Move to Review once wording received. Stefanus to send proposed wording.
</p></blockquote>

<p><i>[
2009-10-24 Stefanus supplied wording.
]</i></p>


<blockquote><p>
Move to Review once wording received. Stefanus to send proposed wording.
Old proposed wording here:
</p><blockquote>
<p>
I think we could fix this by rewording 25.3, p2 to read somthing like:
</p>
<blockquote><p>
-2- <code>Compare</code> is <del>used as a function object which returns
<code>true</code> if the first argument</del> <ins>a <code>BinaryPredicate</code>. The
return value of the function call operator applied to an object of type
<code>Compare</code>, when converted to type <code>bool</code>, yields <code>true</code>
if the first argument of the call</ins> is less than the second, and
<code>false</code> otherwise. <code>Compare <i>comp</i></code> is used throughout for
algorithms assuming an ordering relation. It is assumed that <code><i>comp</i></code>
will not apply any non-constant function through the dereferenced iterator.
</p></blockquote>
</blockquote>
</blockquote>

<p><i>[
2010-01-17:
]</i></p>


<blockquote>
<p>
Howard expresses concern that the current direction of the proposed
wording outlaws expressions such as:
</p>

<blockquote><pre>
if (!comp(x, y))
</pre></blockquote>

<p>
Daniel provides wording which addresses that concern.
</p>

<p>
The previous wording is saved here:
</p>

<blockquote>

<p>
Change 26.8 <a href="https://wg21.link/alg.sorting">[alg.sorting]</a> p2:
</p>
<blockquote><p>
<code>Compare</code> is used as a function object<ins>. The return value of
the function call operator applied to an object of type Compare, when
converted to type bool, yields true if the first argument of the
call</ins> <del>which returns <code>true</code> if the first argument</del>
is less than the second, and <code>false</code> otherwise. <code>Compare
comp</code> is used throughout for algorithms assuming an ordering
relation. It is assumed that <code>comp</code> will not apply any
non-constant function through the dereferenced iterator.
</p></blockquote>

</blockquote>

</blockquote>

<p><i>[
2010-01-22 Moved to Tentatively Ready after 5 positive votes on c++std-lib.
]</i></p>



<p id="res-556"><b>Proposed resolution:</b></p>

<ol>
<li>
<p>
Change 26.1 <a href="https://wg21.link/algorithms.general">[algorithms.general]</a>/7+8 as indicated. <i>[This change is
recommended to bring the return value requirements of <code>BinaryPredicate</code>
and <code>Compare</code> in sync.]</i>
</p>

<blockquote>
<p>
7 The <code>Predicate</code> parameter is used whenever an algorithm expects a
function object that when applied to the result of dereferencing the
corresponding iterator returns a value testable as <code>true</code>. In other
words, if an algorithm takes <code>Predicate pred</code> as its argument and
<code>first</code> as its iterator argument, it should work correctly in the
construct <del>if <code>(pred(*first)){...}</code></del> <ins><code>pred(*first)</code>
contextually converted to <code>bool</code> (7.3 <a href="https://wg21.link/conv">[conv]</a>)</ins>. The
function object <code>pred</code> shall not apply any nonconstant function through
the dereferenced iterator. This function object may be a pointer to function, or
an object of a type with an appropriate function call operator.
</p>

<p>
8 The <code>BinaryPredicate</code> parameter is used whenever an algorithm expects a
function object that when applied to the result of dereferencing two
corresponding iterators or to dereferencing an iterator and type <code>T</code> when
<code>T</code> is part of the signature returns a value testable as <code>true</code>.
In other words, if an algorithm takes <code>BinaryPredicate</code>
<code>binary_pred</code> as its argument and <code>first1</code> and <code>first2</code> as
its iterator arguments, it should work correctly in the construct <del><code>if
(binary_pred(*first1, *first2)){...}</code></del> <ins><code>binary_pred(*first1,
*first2)</code> contextually converted to <code>bool</code> (7.3 <a href="https://wg21.link/conv">[conv]</a>)</ins>. <code>BinaryPredicate</code> always takes the first iterator
type as its first argument, that is, in those cases when <code>T value</code> is
part of the signature, it should work correctly in the <del>context of <code>if
(binary_pred(*first1, value)){...}</code></del> <ins>construct
<code>binary_pred(*first1, value)</code> contextually converted to <code>bool</code>
(7.3 <a href="https://wg21.link/conv">[conv]</a>)</ins>. <code>binary_pred</code> shall not apply any
non-constant function through the dereferenced iterators.
</p>
</blockquote>
</li>

<li>
<p>
Change 26.8 <a href="https://wg21.link/alg.sorting">[alg.sorting]</a>/2 as indicated:
</p>

<blockquote><p>
2 <code>Compare</code> is <del>used as</del> a function object <ins>type (22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>). The return value of the function call operation
applied to an object of type <code>Compare</code>, when contextually converted to
type <code>bool</code> (7.3 <a href="https://wg21.link/conv">[conv]</a>), yields <code>true</code> if the first
argument of the call</ins><del> which returns <code>true</code> if the first
argument</del> is less than the second, and <code>false</code> otherwise.
<code>Compare comp</code> is used throughout for algorithms assuming an ordering
relation. It is assumed that <code>comp</code> will not apply any non-constant
function through the dereferenced iterator.
</p></blockquote>
</li>

</ol>






</body>
</html>
