<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2114: Incorrect "contextually convertible to bool" requirements</title>
<meta property="og:title" content="Issue 2114: Incorrect &quot;contextually convertible to bool&quot; requirements">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2114.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#Resolved">Resolved</a> status.</em></p>
<h3 id="2114"><a href="lwg-defects.html#2114">2114</a>. Incorrect "<em>contextually</em> convertible to <code>bool</code>" requirements</h3>
<p><b>Section:</b> 16.4.4.4 <a href="https://wg21.link/nullablepointer.requirements">[nullablepointer.requirements]</a>, 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a>, 24.3.5.7 <a href="https://wg21.link/random.access.iterators">[random.access.iterators]</a>, 26.1 <a href="https://wg21.link/algorithms.general">[algorithms.general]</a>, 26.8 <a href="https://wg21.link/alg.sorting">[alg.sorting]</a>, 32.2.1 <a href="https://wg21.link/thread.req.paramname">[thread.req.paramname]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2011-12-09 <b>Last modified:</b> 2025-03-13</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="lwg-index.html#nullablepointer.requirements">issues</a> in [nullablepointer.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>

<p>
As of 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> Table 17&#47;18, the return types of the expressions
</p>
<blockquote><pre>
a == b
</pre></blockquote>
<p>
or
</p>
<blockquote><pre>
a &lt; b
</pre></blockquote>
<p>
for types satisfying the <code>EqualityComparable</code> or <code>LessThanComparable</code>
types, respectively, are required to be "convertible to <code>bool</code>" which corresponds to
a copy-initialization context. But several newer parts of the library that refer to 
such contexts have lowered the requirements taking  advantage of the new terminology of 
"<em>contextually</em> convertible to <code>bool</code>" instead, which corresponds to a 
direct-initialization context (In addition to "normal" direct-initialization constructions, 
operands of logical operations as well as <code>if</code> or <code>switch</code> conditions also 
belong to this special context).
<p/>
One example for these new requirements are input iterators which satisfy <code>EqualityComparable</code> 
but also specify that the expression
</p>
<blockquote><pre>
a != b
</pre></blockquote>
<p>
shall be just "<strong>contextually</strong> convertible to <code>bool</code>". The same discrepancy 
exists for requirement set <code>NullablePointer</code> in regard to several equality-related expressions.
<p/>
For random access iterators we have
</p>
<blockquote><p>
<code>a &lt; b</code>      contextually convertible to <code>bool</code>
</p></blockquote>
<p>
as well as for all derived comparison functions, so strictly speaking we could have a random access 
iterator that does not satisfy the <code>LessThanComparable</code> requirements, which looks like an
artifact to me.
<p/>
Even if we keep with the existing requirements based on <code>LessThanComparable</code> or
<code>EqualityComparable</code> we still would have the problem that some current specifications 
are actually  based on the assumption of implicit convertibility instead of "explicit convertibility", e.g. 
20.3.1.6 <a href="https://wg21.link/unique.ptr.special">[unique.ptr.special]</a> p3:
</p>
<blockquote><pre>
template &lt;class T1, class D1, class T2, class D2&gt;
bool operator!=(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
</pre>
<blockquote>
<p>
-3- <i>Returns</i>: <code>x.get() != y.get()</code>.
</p>
</blockquote></blockquote>
<p>
Similar examples exist in 20.3.1.3.3 <a href="https://wg21.link/unique.ptr.single.dtor">[unique.ptr.single.dtor]</a> p2, 20.3.1.3.4 <a href="https://wg21.link/unique.ptr.single.asgn">[unique.ptr.single.asgn]</a> p9,
20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a> p1+3+8, etc.
<p/>
In all these places the expressions involving comparison functions (but <em>not</em> those of the conversion 
of a <code>NullablePointer</code> to <code>bool</code>!) assume to be "convertible to <code>bool</code>". I think this
is a very natural assumption and all delegations of the comparison functions of some type <code>X</code> to some
other API type <code>Y</code> in third-party code does so assuming that copy-initialization semantics will
just work.
<p/>
The actual reason for using the newer terminology can be rooted back to LWG <a href="lwg-defects.html#556" title="Is Compare a BinaryPredicate? (Status: C++11)">556</a><sup><a href="https://cplusplus.github.io/LWG/issue556" title="Latest snapshot">(i)</a></sup>. My hypotheses 
is that the resolution of that issue also needs a slight correction. Why so?
<p/>
The reason for opening that issue were worries based on the previous "convertible to <code>bool</code>"
wording. An expressions like "<code>!pred(a, b)</code>" might not be well-formed in those situations, because
<code>operator!</code> might not be accessible or might have an unusual semantics (and similarly for other logical
operations). This can indeed happen with unusual proxy return types, so the idea was that the evaluation of 
<code>Predicate</code>, <code>BinaryPredicate</code> (26.1 <a href="https://wg21.link/algorithms.general">[algorithms.general]</a> p8+9), and <code>Compare</code> 
(26.8 <a href="https://wg21.link/alg.sorting">[alg.sorting]</a> p2) should be defined based on contextual conversion to <code>bool</code>. 
Unfortunately this <em>alone</em> is not sufficient: In addition, I think, we <em>also</em> want the predicates 
to be (implicitly) convertible to <code>bool</code>! Without this wording, several conditions are plain wrong, 
e.g. 26.6.6 <a href="https://wg21.link/alg.find">[alg.find]</a> p2, which talks about "<code>pred(*i) != false</code>" (<code>find_if</code>) and 
"<code>pred(*i) == false</code>" (<code>find_if_not</code>). These expressions are not within a boolean context! 
<p/>
While we could simply fix all these places by proper wording to be considered in a "contextual conversion to
<code>bool</code>", I think that this is not the correct solution: Many third-party libraries already refer to
the previous C++03 <code>Predicate</code> definition &mdash; it actually predates C++98 and is as old as the 
<a href="https://www.boost.org/sgi/stl/Predicate.html">SGI specification</a>. It seems to be a high price to
pay to switch to direct initialization here instead of fixing a completely different specification problem.
<p/>
A final observation is that we have another definition for a <code>Predicate</code> in 32.2.1 <a href="https://wg21.link/thread.req.paramname">[thread.req.paramname]</a> p2:
</p>
<blockquote><p>
If a parameter is <code>Predicate</code>, <code>operator()</code> applied to the actual template argument shall return a value that
is convertible to <code>bool</code>.
</p></blockquote>
<p>
The problem here is not that we have two different definitions of <code>Predicate</code> in the standard &mdash; this 
is confusing, but this fact alone is not a defect. The first (minor) problem is that this definition does not properly 
apply to function objects that are function pointers, because <code>operator()</code> is not defined in a strict sense. 
But the actually worse second problem is that this wording has the very <code>same</code> problem that has originally lead to
LWG <a href="lwg-defects.html#556" title="Is Compare a BinaryPredicate? (Status: C++11)">556</a><sup><a href="https://cplusplus.github.io/LWG/issue556" title="Latest snapshot">(i)</a></sup>! We only need to look at 32.7.4 <a href="https://wg21.link/thread.condition.condvar">[thread.condition.condvar]</a> p15 to recognice this:
</p>
<blockquote><pre>
while (!pred())
  wait(lock);
</pre></blockquote>
<p>
The negation expression here looks very familiar to the example provided in LWG <a href="lwg-defects.html#556" title="Is Compare a BinaryPredicate? (Status: C++11)">556</a><sup><a href="https://cplusplus.github.io/LWG/issue556" title="Latest snapshot">(i)</a></sup> and is sensitive
to the same "unusual proxy" problem. Changing the 32.2.1 <a href="https://wg21.link/thread.req.paramname">[thread.req.paramname]</a> wording to a corresponding
"contextual conversion to <code>bool</code>" wouldn't work either, because existing specifications rely on "convertible
to <code>bool</code>", e.g. 32.7.4 <a href="https://wg21.link/thread.condition.condvar">[thread.condition.condvar]</a> p32+33+42 or 32.7.5 <a href="https://wg21.link/thread.condition.condvarany">[thread.condition.condvarany]</a> 
p25+26+32+33.
<p/>
To summarize: I believe that LWG <a href="lwg-defects.html#556" title="Is Compare a BinaryPredicate? (Status: C++11)">556</a><sup><a href="https://cplusplus.github.io/LWG/issue556" title="Latest snapshot">(i)</a></sup> was not completely resolved. A pessimistic interpretation is,
that even with the current wording based on "contextually convertible to <code>bool</code>" the actual problem of that 
issue has <em>not</em> been fixed. What actually needs to be required here is some normative wording that basically
expresses something along the lines of:
</p>
<blockquote><p>
The semantics of <em>any</em> contextual conversion to <code>bool</code> shall be equivalent to the semantics of 
any implicit conversion to <code>bool</code>.
</p></blockquote>
<p>
This is still not complete without having concepts, but it seems to be a better approximation. Another way of solving
this issue would be to define a minimum requirements table with equivalent semantics. The proposed wording is a bit
simpler but attempts to express the same thing.
</p>

<p><i>[2012, Kona]</i></p>

<p>
Agree with Daniel that we potentially broke some C++03 user code, accept the changes striking
"contextually" from tables. Stefan to provide revised wording for section 25, and figure out
changes to section 30.
</p>
<p>
Move to open, and then to Review when updated wording from Stefan is available.
</p>

<p><i>[2012-10-12, STL comments]</i></p>


<ol>
<li>
<p>
The current proposed resolution still isn't completely satisfying. It would certainly be possible for the Standard to 
require these various expressions to be implicitly and contextually convertible to <code>bool</code>, but that would have 
a subtle consequence (which, I will argue, is undesirable - regardless of the fact that it dates all the way back to 
C++98/03). It would allow users to provide really wacky types to the Standard Library, with one of two effects:
</p>
<ol style="list-style-type:upper-alpha">
<li>
<p>Standard Library implementations would have to go to great lengths to respect such wacky types, essentially using 
<code>static_cast&lt;bool&gt;</code> when invoking any predicates or comparators.
</p>
</li>

<li>
<p>
Otherwise, such wacky types would be de facto nonportable, because they would make Standard Library implementations 
explode.
</p>
</li>
</ol>

<p>
Effect B is the status quo we're living with today. What Standard Library implementations want to do with <code>pred(args)</code> 
goes beyond "<code>if (pred(args))</code>" (C++03), contextually converting <code>pred(args)</code> to <code>bool</code> (C++11), or 
implicitly and contextually converting <code>pred(args)</code> to <code>bool</code> (the current proposed resolution). 
Implementations want to say things like:
</p>

<blockquote><pre>
if (pred(args))
if (!pred(args))
if (cond &amp;&amp; pred(args))
if (cond &amp;&amp; !pred(args))
</pre></blockquote>

<p>
These are real examples taken from Dinkumware's implementation. There are others that would be realistic 
("<code>pred(args) &amp;&amp; cond</code>", "<code>cond || pred(args)</code>", etc.)
<p/>
Although negation was mentioned in this issue's Discussion section, and in LWG <a href="lwg-defects.html#556" title="Is Compare a BinaryPredicate? (Status: C++11)">556</a><sup><a href="https://cplusplus.github.io/LWG/issue556" title="Latest snapshot">(i)</a></sup>'s, the current proposed 
resolution doesn't fix this problem. Requiring <code>pred(args)</code> to be implicitly and contextually convertible to <code>bool</code> 
doesn't prevent <code>operator!()</code> from being overloaded and returning <code>std::string</code> (as a wacky example). More 
ominously, it doesn't prevent <code>operator&amp;&amp;()</code> and <code>operator||()</code> from being overloaded and destroying 
short-circuiting.
</p>

</li>

<li>
<p>
I would like LWG input before working on Standardese for a new proposed resolution. Here's an outline of what I'd like to 
do:
</p>
<ol style="list-style-type:upper-alpha">
<li>
<p>
Introduce a new "concept" in 16.4.4 <a href="https://wg21.link/utility.requirements">[utility.requirements]</a>, which I would call <code>BooleanTestable</code> in the 
absence of better ideas.
</p>
</li>

<li>
<p>
Centralize things and reduce verbosity by having everything simply refer to <code>BooleanTestable</code> when necessary. 
I believe that the tables could say "Return type: <code>BooleanTestable</code>", while Predicate/BinaryPredicate/Compare 
would need the incantation "shall satisfy the requirements of BooleanTestable".
</p>
</li>

<li>
<p>
Resolve the tug-of-war between users (who occasionally want to do weird things) and implementers (who don't want to have 
to contort their code) by requiring that:
</p>
<ol style="list-style-type:upper-roman">
<li>
<p>
Given a <code>BooleanTestable x</code>, <code>x</code> is both implicitly and contextually convertible to <code>bool</code>.
</p>
</li>

<li>
<p>
Given a <code>BooleanTestable x</code>, <code>!x</code> is <code>BooleanTestable</code>. (This is intentionally "recursive".)
</p>
</li>

<li>
<p>
Given a <code>BooleanTestable x</code>, <code>bool t = x, t2(x), f = !x;</code> has the postcondition <code>t == t2 &amp;&amp; t != f</code>.
</p>
</li>

<li>
<p>
Given a <code>BooleanTestable x</code> and a <code>BooleanTestable y</code> of possibly different types, "<code>x &amp;&amp; y</code>" 
and "<code>x || y</code>" invoke the built-in <code>operator&amp;&amp;()</code> and <code>operator||()</code>, triggering short-circuiting.
</p>
</li>

<li>
<p>
<code>bool</code> is <code>BooleanTestable</code>.
</p>
</li>
</ol>

</li>

</ol>

<p>
 I believe that this simultaneously gives users great latitude to use types other than <code>bool</code>, while allowing 
 implementers to write reasonable code in order to get their jobs done. (If I'm forgetting anything that implementers 
 would want to say, please let me know.)
</p>

</li>

<li>
<p>
About requirement (I): As Daniel patiently explained to me, we need to talk about both implicit conversions and 
contextual conversions, because it's possible for a devious type to have both "<code>explicit operator bool()</code>" 
and "<code>operator int()</code>", which might behave differently (or be deleted, etc.).
</p>
</li>

<li>
<p>
About requirement (IV): This is kind of tricky. What we'd like to say is, "<code>BooleanTestable</code> can't ever trigger 
an overloaded logical operator". However, given a perfectly reasonable type <code>Nice</code> - perhaps even <code>bool</code> itself! - 
other code (perhaps a third-party library) could overload <code>operator&amp;&amp;(Nice, Evil)</code>. Therefore, I believe 
that the requirement should be "no first use" - the Standard Library will ask for various <code>BooleanTestable</code> types 
from users (for example, the result of "<code>first != last</code>" and the result of "<code>pred(args)</code>"), and as long 
as they don't trigger overloaded logical operators with each other, everything is awesome.
</p>
</li>


<li>
<p>
About requirement (V): This is possibly redundant, but it's trivial to specify, makes it easier for users to understand 
what they need to do ("oh, I can always achieve this with <code>bool</code>"), and provides a "base case" for requirement 
(IV) that may or may not be necessary.  Since <code>bool</code> is <code>BooleanTestable</code>, overloading 
<code>operator&amp;&amp;(bool, Other)</code> (etc.) clearly makes the <code>Other</code> type non-<code>BooleanTestable</code>.
</p>
</li>
</ol>

<strong>Previous resolution from Daniel [SUPERSEDED]:</strong>
<p/>
<blockquote class="note">
<p>This wording is relative to the FDIS.</p>

<ol>
<li><p>Change Table 25 &mdash; "<code>NullablePointer</code> requirements" in 16.4.4.4 <a href="https://wg21.link/nullablepointer.requirements">[nullablepointer.requirements]</a>
as indicated:</p>

<table border="1">
<caption>Table 25 &mdash; <code>NullablePointer</code> requirements</caption>
<tr align="center">
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
</tr> 

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

<tr>
<td>
<code>a != b</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>!(a == b)</code>
</td>
</tr>

<tr>
<td>
<code>a == np<br/>
np == a</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>a == P()</code>
</td>
</tr>

<tr>
<td>
<code>a != np<br/>
np != a</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>!(a == np)</code>
</td>
</tr>

</table>
 
</li>

<li><p>Change Table 107 &mdash; "Input iterator requirements" in 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a>
as indicated:</p>

<table border="1">
<caption>Table 107 &mdash; Input iterator requirements (in addition to Iterator)</caption>
<tr align="center">
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr> 

<tr>
<td>
<code>a != b</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>!(a == b)</code>
</td>
<td>
pre: <code>(a, b)</code> is in the domain of <code>==</code>.
</td>
</tr>

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

</table>
 
</li>

<li><p>Change Table 111 &mdash; "Random access iterator requirements" in 24.3.5.7 <a href="https://wg21.link/random.access.iterators">[random.access.iterators]</a>
as indicated:</p>

<table border="1">
<caption>Table 111 &mdash; Random access iterator requirements (in addition to bidirectional iterator)</caption>
<tr align="center">
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr> 

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

<tr>
<td>
<code>a &lt; b</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>b - a &gt; 0</code>
</td>
<td>
<code>&lt;</code> is a total ordering relation
</td>
</tr>

<tr>
<td>
<code>a &gt; b</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>b &lt; a</code>
</td>
<td>
<code>&gt;</code> is a total ordering relation opposite to <code>&lt;</code>.
</td>
</tr>

<tr>
<td>
<code>a &gt;= b</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>!(a &lt; b)</code>
</td>
<td>
</td>
</tr>

<tr>
<td>
<code>a &lt;= b</code>
</td>
<td>
<del>contextually</del> convertible to <code>bool</code>
</td>
<td>
<code>!(a &gt; b)</code>
</td>
<td>
</td>
</tr>

</table>
 
</li>

<li><p>Change 26.1 <a href="https://wg21.link/algorithms.general">[algorithms.general]</a> p8+9 as indicated:</p>

<blockquote>
<p>
-8- The <code>Predicate</code> parameter is used whenever an algorithm expects a function object 
(22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>) 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 first as its iterator argument, it should work correctly in the construct 
<code>pred(*first)</code> <ins>implicitly or</ins> contextually converted to <code>bool</code> (Clause 7.3 <a href="https://wg21.link/conv">[conv]</a>). 
The function object <code>pred</code> shall not apply any non-constant function through the dereferenced iterator.
<p/>
-9- 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 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 <code>binary_pred(*first1, *first2)</code> <ins>implicitly or</ins> contextually converted to 
<code>bool</code> (Clause 7.3 <a href="https://wg21.link/conv">[conv]</a>).
<code>BinaryPredicate</code> always takes the first iterator's <code>value_type</code> as its first argument, that is, in those cases
when <code>T</code> value is part of the signature, it should work correctly in the construct <code>binary_pred(*first1, value)</code> 
<ins>implicitly or</ins> contextually converted to <code>bool</code> (Clause 7.3 <a href="https://wg21.link/conv">[conv]</a>). <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> p2 as indicated:</p>

<blockquote>
<p>
-2- <code>Compare</code> is a function object 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 <ins>implicitly or</ins> contextually converted 
to <code>bool</code> (7.3 <a href="https://wg21.link/conv">[conv]</a>), yields <code>true</code> if the first argument of the call 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>

<li><p>Change 32.2.1 <a href="https://wg21.link/thread.req.paramname">[thread.req.paramname]</a> p2 as indicated:</p>

<blockquote>
<p>
-2- <del>If a parameter is <code>Predicate</code>, operator() applied to the actual template argument shall return a value that
is convertible to <code>bool</code></del><ins><code>Predicate</code> is a function object 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>Predicate</code>, when implicitly or 
contextually converted to <code>bool</code> (7.3 <a href="https://wg21.link/conv">[conv]</a>), yields <code>true</code> if the corresponding test condition is
satisfied, and <code>false</code> otherwise</ins>.
</p>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2014-05-20, Daniel suggests concrete wording based on STL's proposal]</i></p>

<p>
The presented wording follows relatively closely STL's outline with the following notable exceptions:
</p>
<ol style="list-style-type:upper-alpha">
<li><p>
A reference to <code>BooleanTestable</code> in table "Return Type" specifications seemed very unusual to me and
I found no "prior art" for this in the Standard. Instead I decided to follow the usual style to add a symbol
with a specific meaning to a specific paragraph that specifies symbols and their meanings.
</p></li>
<li><p>
STL's requirement IV suggested to directly refer to built-in operators <code>&amp;&amp;</code> and <code>||</code>. In my
opinion this concrete requirement isn't needed if we simply require that two <code>BooleanTestable</code> operands behave 
equivalently to two those operands after conversion to <code>bool</code> (each of them).
</p></li>
<li><p>
I couldn't find a good reason to require normatively that type <code>bool</code> meets the requirements of <code>BooleanTestable</code>: My
assertion is that after having defined them, the result simply falls out of this. But to make this a bit clearer, I added
also a non-normative note to these effects.
</p></li>
</ol>

<p><i>[2014-06-10, STL comments]</i></p>

<p>
In the current wording I would like to see changed the suggested changes described by bullet #6:
</p>
<ol style="list-style-type:upper-alpha">
<li><p>In 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> p4 undo the suggested change</p></li>
<li><p>Then change the 7 occurrences of "convertible to <code>bool</code>" in the denoted tables to "<code>bool</code>".</p></li>
</ol>

<p><i>[2015-05-05 Lenexa]</i></p>

<p>STL: Alisdair wanted to do something here, but Daniel gave us updated wording.</p>

<p><i>[2015-07 Telecon]</i></p>
<p>
Alisdair: Should specify we don't break short circuiting.<br/>
Ville: Looks already specified because that's the way it works for bool. <br/>
Geoffrey: Maybe add a note about the short circuiting.<br/>
B2/P2 is somewhat ambiguous. It implies that B has to be both implicitly convertible to bool and contextually convertible to bool.<br/>
We like this, just have nits.<br/>
Status stays Open.<br/>
Marshall to ping Daniel with feedback.<br/>
</p>

<p><i>[2016-02-27, Daniel updates wording]</i></p>

<ol>
<li>
<p>
The revised wording has been updated from N3936 to N4567. 
</p>
</li>
<li>
<p>
To satisfy the Kona 2015 committee comments, the wording in 
[booleantestable.requirements] has been improved to better separate the two different requirements of "can be 
contextually converted to <code>bool</code>" and "can be implicitly converted to <code>bool</code>. Both are necessary because 
it is possible to define a type that has the latter property but not the former, such as the following one:
</p>
<blockquote class="note">
<p>
2016-08-07, Daniel: The below example has been corrected to reduce confusion about the performed conversions as indicated
by the delta markers:
</p>
</blockquote>
<blockquote><pre>
using Bool = int;

struct OddBoolean 
{
  explicit <ins>operator bool() const = delete;
  operator Bool() const;</ins>
  <del>OddBoolean(bool) = delete;
  OddBoolean(Bool){}</del>
} <ins>ob</ins>;

<ins>bool b2 = ob; // OK
bool b1(ob);  // Error</ins>
<del>OddBoolean b2 = true; // OK
OddBoolean b1(true);  // Error</del>
<ins></ins>
</pre></blockquote>
</li>
<li>
<p>
In [booleantestable.requirements] a note has been added to ensure that an implementation is not allowed to 
break any short-circuiting semantics.
</p>
</li>
<li>
<p>
I decided to separate LWG <a href="lwg-defects.html#2587" title="&quot;Convertible to bool&quot; requirement in conjunction and disjunction (Status: C++17)">2587</a><sup><a href="https://cplusplus.github.io/LWG/issue2587" title="Latest snapshot">(i)</a></sup>/<a href="lwg-defects.html#2588" title="[fund.ts.v2] &quot;Convertible to bool&quot; requirement in conjunction and disjunction (Status: TS)">2588</a><sup><a href="https://cplusplus.github.io/LWG/issue2588" title="Latest snapshot">(i)</a></sup> from this issue. Both these issues aren't exactly the
same but depending on the committee's position, their resolution might benefit from the new vocabulary introduced
here.
</p>
</li>
</ol>

<p><i>[2021-06-25; Daniel comments]</i></p>

<p>
The paper <a href="https://wg21.link/P2167R1" title=" Improved Proposed Wording for LWG 2114 (contextually convertible to bool)">P2167R1</a> is provided to resolve this issue.
</p>

<p><i>[2022-05-01; Daniel comments]</i></p>

<p>
The paper <a href="https://isocpp.org/files/papers/P2167R2.html">P2167R2</a> is provided to resolve this issue.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to N4567.</p>

<ol>
<li><p>Change 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> p1, Table 17 &mdash; "EqualityComparable requirements", and
Table 18 &mdash; "LessThanComparable requirements" as indicated:</p>

<blockquote>
<p>
-1- [&hellip;] In these tables, <code>T</code> is an object or reference type to be supplied by a C++ program
instantiating a template; <code>a</code>, <code>b</code>, and <code>c</code> are values of type (possibly <code>const</code>) <code>T</code>; 
<code>s</code> and <code>t</code> are modifiable lvalues of type <code>T</code>; <code>u</code> denotes an identifier; <code>rv</code> 
is an rvalue of type <code>T</code>; <del>and</del> <code>v</code> is an lvalue of type (possibly <code>const</code>) <code>T</code> or an
rvalue of type <code>const T</code><ins>; and <code>BT</code> denotes a type that meets the <code>BooleanTestable</code> 
requirements ([booleantestable.requirements])</ins>.
<p/>
[&hellip;]
</p>
<blockquote>
<table border="1">
<caption>Table 17 &mdash; <code>EqualityComparable</code> requirements [equalitycomparable]</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">Requirement</th>
</tr>

<tr>
<td>
<code>a == b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
<code>==</code> is an equivalence relation, that is, it has the
following properties: [&hellip;]
</td>
</tr>

</table>
</blockquote>
<p>
[&hellip;]
</p>
<blockquote>
<table border="1">
<caption>Table 18 &mdash; <code>LessThanComparable</code> requirements [lessthancomparable]</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">Requirement</th>
</tr>

<tr>
<td>
<code>a &lt; b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
<code>&lt;</code> is a strict weak ordering relation (26.8 <a href="https://wg21.link/alg.sorting">[alg.sorting]</a>)
</td>
</tr>

</table>
</blockquote>

</blockquote>

</li>

<li><p>Between 16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a> and 16.4.4.4 <a href="https://wg21.link/nullablepointer.requirements">[nullablepointer.requirements]</a> insert a new sub-clause 
as indicated:</p>

<blockquote>
?.?.?.? <b><code>BooleanTestable</code> requirements [booleantestable.requirements]</b>  
<blockquote>
<p>
-?- A <code>BooleanTestable</code> type is a boolean-like type that also supports conversions to <code>bool</code>.
A type <code>B</code> meets the <code>BooleanTestable</code> requirements if the expressions described in Table ?? are valid 
and have the indicated semantics, and if <code>B</code> also satisfies all the other requirements of this sub-clause 
[booleantestable.requirements].
<p/>
An object <code>b</code> of type <code>B</code> can be implicitly converted to <code>bool</code> and in addition can be 
contextually converted to <code>bool</code> (Clause 4). The result values of both kinds of conversions shall be equivalent. 
<p/>
[<i>Example</i>: The types <code>bool</code>, <code>std::true_type</code>, and <code>std::bitset&lt;&gt;::reference</code> are 
<code>BooleanTestable</code> types. &mdash; <i>end example</i>]
<p/>
For the purpose of Table ??, let <code>B2</code> and <code>Bn</code> denote types (possibly both equal to <code>B</code> or to each other) 
that meet the <code>BooleanTestable</code> requirements, let <code>b1</code> denote a (possibly <code>const</code>) value of <code>B</code>, 
let <code>b2</code> denote a (possibly <code>const</code>) value of <code>B2</code>, and let <code>t1</code> denote a value of type 
<code>bool</code>.
<p/>
[<i>Note</i>: These rules ensure what an implementation can rely on but doesn't grant it
license to break short-circuiting behavior of a <code>BooleanTestable</code> type. &mdash; <i>end note</i>]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Somewhere within the new sub-clause [booleantestable.requirements] insert the following new Table (?? denotes
the assigned table number):</p>

<blockquote>
<table border="1">
<caption>Table ?? &mdash; <code>BooleanTestable</code> requirements [booleantestable]</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">Operational semantics</th>
</tr>

<tr>
<td>
<code>bool(b1)</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<i>Remarks</i>: <code>bool(b1) == t1</code> for every value<br/>
<code>b1</code> implicitly converted to <code>t1</code>.
</td>
</tr>

<tr>
<td>
<code>!b1</code>
</td>
<td>
<code>Bn</code>
</td>
<td>
<i>Remarks</i>: <code>bool(b1) == !bool(!b1)</code> for<br/>
every value <code>b1</code>.
</td>
</tr>

<tr>
<td>
<code>b1 &amp;&amp; b2</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<code>bool(b1) &amp;&amp; bool(b2)</code>
</td>
</tr>

<tr>
<td>
<code>b1 || b2</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<code>bool(b1) || bool(b2)</code>
</td>
</tr>

</table>
</blockquote>

</li>

<li><p>Change 16.4.4.4 <a href="https://wg21.link/nullablepointer.requirements">[nullablepointer.requirements]</a> p5 and Table 25 &mdash; "NullablePointer requirements" as indicated:</p>

<blockquote>
<p>
[&hellip;]
<p/>
-5- In Table 25, <code>u</code> denotes an identifier, <code>t</code> denotes a non-<code>const</code> lvalue of type <code>P</code>, <code>a</code> 
and <code>b</code> denote values of type (possibly <code>const</code>) <code>P</code>, <del>and</del> <code>np</code> denotes a value of type 
(possibly <code>const</code>) <code>std::nullptr_t</code><ins>, and <code>BT</code> denotes a type that meets the <code>BooleanTestable</code> 
requirements ([booleantestable.requirements])</ins>.
<p/>
[&hellip;]
</p>
<blockquote>
<table border="1">
<caption>Table 25 &mdash; <code>NullablePointer</code> requirements [nullablepointer]</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">Operational semantics</th>
</tr>

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

<tr>
<td>
<code>a != b</code>
</td>
<td>
<del>contextually convertible to <code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a == np</code><br/>
<code>np == a</code>
</td>
<td>
<del>contextually convertible to <code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a != np</code><br/>
<code>np != a</code>
</td>
<td>
<del>contextually convertible to <code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

</table>
</blockquote>
</blockquote>
</li>

<li><p>Change 22.4.9 <a href="https://wg21.link/tuple.rel">[tuple.rel]</a> as indicated;</p>

<blockquote>
<pre>
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator==(const tuple&lt;TTypes...&gt;&amp; t, const tuple&lt;UTypes...&gt;&amp; u);
</pre>
<blockquote>
<p>
-1- <i>Requires</i>: For all <code>i</code>, where <code>0 &lt;= i</code> and <code>i &lt; sizeof...(TTypes)</code>, 
<code>get&lt;i&gt;(t) == get&lt;i&gt;(u)</code> is a valid expression returning a type that <del>is convertible to 
<code>bool</code></del><ins>meets the <code>BooleanTestable</code> requirements ([booleantestable.requirements])</ins>. 
<code>sizeof...(TTypes) == sizeof...(UTypes)</code>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator&lt;(const tuple&lt;TTypes...&gt;&amp; t, const tuple&lt;UTypes...&gt;&amp; u);
</pre>
<blockquote>
<p>
-4- <i>Requires</i>: For all <code>i</code>, where <code>0 &lt;= i</code> and <code>i &lt; sizeof...(TTypes)</code>, 
<code>get&lt;i&gt;(t) &lt; get&lt;i&gt;(u)</code> and <code>get&lt;i&gt;(u) &lt; get&lt;i&gt;(t)</code> are valid 
expressions returning types that <del>are convertible to 
<code>bool</code></del><ins>meet the <code>BooleanTestable</code> requirements ([booleantestable.requirements])</ins>. 
<code>sizeof...(TTypes) == sizeof...(UTypes)</code>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Change 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a>, Table 95 &mdash; "Container requirements", and
Table 97 &mdash; "Optional container operations" as indicated:</p>

<blockquote>
<p>
-4- In Tables 95, 96, and 97 <code>X</code> denotes a container class containing objects of type <code>T</code>, <code>a</code> and 
<code>b</code> denote values of type <code>X</code>, <code>u</code> denotes an identifier, <code>r</code> denotes a non-<code>const</code> value 
of type <code>X</code>, <del>and</del> <code>rv</code> denotes a non-<code>const</code> rvalue of type <code>X</code><ins>, and <code>BT</code> 
denotes a type that meets the <code>BooleanTestable</code> requirements ([booleantestable.requirements])</ins>.
</p>
<blockquote>
<table border="1">
<caption>Table 95 &mdash; Container requirements</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">[&hellip;]</th>
</tr>

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

<tr>
<td>
<code>a == b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a != b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

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

<tr>
<td>
<code>a.empty()</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

</table>
</blockquote>
<p>
[&hellip;]
</p>
<blockquote>
<table border="1">
<caption>Table 97 &mdash; Optional container requirements</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">[&hellip;]</th>
</tr>

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

<tr>
<td>
<code>a &lt; b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a &gt; b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a &lt;= b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a &gt;= b</code>
</td>
<td>
<del>convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

</table>
</blockquote>
</blockquote>
</li>

<li><p>Change 24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>, Table 106 &mdash; "Input iterator requirements", and
Table 110 &mdash; "Random access iterator requirements" as indicated:</p>

<blockquote>
<p>
-12- In the following sections, <code>a</code> and <code>b</code> denote values of type <code>X</code> or <code>const X</code>, 
<code>difference_type</code> and <code>reference</code> refer to the types <code>iterator_traits&lt;X&gt;::difference_type</code> and 
<code>iterator_traits&lt;X&gt;::reference</code>, respectively, <code>n</code> denotes a value of <code>difference_type</code>, <code>u</code>, 
<code>tmp</code>, and <code>m</code> denote identifiers, <code>r</code> denotes a value of <code>X&amp;</code>, <code>t</code> denotes
a value of value type <code>T</code>, <code>o</code> denotes a value of some type that is writable to the output iterator<ins>, and <code>BT</code> 
denotes a type that meets the <code>BooleanTestable</code> requirements ([booleantestable.requirements])</ins>.
</p>
<blockquote>
<table border="1">
<caption>Table 106 &mdash; Input iterator requirements</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">[&hellip;]</th>
</tr>

<tr>
<td>
<code>a != b</code>
</td>
<td>
<del>contextually convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>
</table>
</blockquote>
<p>
[&hellip;]
</p>
<blockquote>
<table border="1">
<caption>Table 110 &mdash; Random access iterator requirements</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">[&hellip;]</th>
</tr>

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

<tr>
<td>
<code>a &lt; b</code>
</td>
<td>
<del>contextually convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a &gt; b</code>
</td>
<td>
<del>contextually convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a &gt;= b</code>
</td>
<td>
<del>contextually convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>a &lt;= b</code>
</td>
<td>
<del>contextually convertible to<br/>
<code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

</table>
</blockquote>
</blockquote>
</li>

<li><p>Change 26.1 <a href="https://wg21.link/algorithms.general">[algorithms.general]</a> p8+p9 as indicated:</p>
<blockquote class="note">
<p>
[<i>Drafting note</i>: The wording changes below also fix
(a) unusual wording forms used ("should work") which are unclear in which sense they are imposing normative requirements and
(b) the problem, that the current wording seems to allow that the predicate may mutate a call argument, if that is not a 
dereferenced iterator.
Upon applying the new wording it became obvious that the both the previous and the new wording has the effect that currently 
algorithms such as <code>adjacent_find</code>, <code>search_n</code>, <code>unique</code>, and <code>unique_copy</code> are not correctly 
described (because they have no iterator argument named <code>first1</code>), which could give raise to a new library issue. 
&mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<p>
-8- The <code>Predicate</code> parameter is used whenever an algorithm expects a function object (20.9) that, when applied
to the result of dereferencing the corresponding iterator, returns a value testable as <code>true</code>. <del>In other words,
i</del><ins>I</ins>f an algorithm takes <code>Predicate pred</code> as its argument and <code>first</code> as its iterator argument, 
<del>it should work correctly in the construct <code>pred(*first)</code> contextually converted to 
<code>bool</code> (Clause 4)</del><ins>the expression <code>pred(*first)</code> shall have a type that meets the <code>BooleanTestable</code> 
requirements ( [booleantestable.requirements])</ins>. 
The function object <code>pred</code> shall not apply any non-constant function through <del>the dereferenced 
iterator</del><ins>its argument</ins>.
<p/>
-9- 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>. <del>In other words, 
i</del><ins>I</ins>f an algorithm takes <code>BinaryPredicate binary_pred</code> as its argument and <code>first1</code> and 
<code>first2</code> as its iterator arguments, <del>it should work correctly in the construct <code>binary_pred(*first1, *first2)</code> 
contextually converted to <code>bool</code> (Clause 4)</del><ins>the expression <code>binary_pred(*first1, *first2)</code> shall 
have a type that meets the <code>BooleanTestable</code> requirements ( [booleantestable.requirements])</ins>. 
<code>BinaryPredicate</code> always takes the first iterator's <code>value_type</code> as its first argument, that is, in those cases 
when <code>T</code> value is part of the signature, <del>it should work correctly in the construct <code>binary_pred(*first1, value)</code> 
contextually converted to <code>bool</code> (Clause 4)</del><ins>the expression <code>binary_pred(*first1, value)</code> shall have a 
type that meets the <code>BooleanTestable</code> requirements ( [booleantestable.requirements])</ins>. <code>binary_pred</code> 
shall not apply any non-constant function through <del>the dereferenced iterators</del><ins>any of its arguments</ins>.
</p>
</blockquote>
</li>

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

<blockquote>
<p>
[&hellip;]
<p/>
-2- <code>Compare</code> is a function object type (20.9). <del>The return value of the function call 
operation applied to an object of type <code>Compare</code>, when contextually converted 
to <code>bool</code>(Clause 4), yields <code>true</code> if the first argument of the call is less than the second, 
and <code>false</code> otherwise.</del> <code>Compare comp</code> is used throughout for algorithms assuming an ordering relation. 
<ins>Let <code>a</code> and <code>b</code> denote two argument values whose types depend on the corresponding algorithm. Then the expression 
<code>comp(a, b)</code> shall have a type that meets the <code>BooleanTestable</code> requirements ( [booleantestable.requirements]).
The return value of <code>comp(a, b)</code>, converted to <code>bool</code>, yields <code>true</code> if the 
first argument <code>a</code> is less than the second argument <code>b</code>, and <code>false</code> otherwise.</ins> It is assumed that 
<code>comp</code> will not apply any non-constant function through <del>the dereferenced iterator</del><ins>any of its arguments</ins>.
<p/>
[&hellip;]
</p>
</blockquote>
</li>

<li><p>Change 31.5.3.3 <a href="https://wg21.link/fpos.operations">[fpos.operations]</a> and Table 126 &mdash; "Position type requirements" as indicated:</p>

<blockquote>
<p>
-1- Operations specified in Table 126 are permitted. In that table,
</p>
<ul>
<li><p><code>P</code> refers to an instance of <code>fpos</code>,</p></li>
<li><p>[&hellip;]</p></li>
<li><p><code>o</code> refers to a value of type <code>streamoff</code>,</p></li>
<li><p><ins><code>BT</code> refers to a type that meets the <code>BooleanTestable</code> requirements ([booleantestable.requirements]),</ins></p></li>
<li><p>[&hellip;]</p></li>
</ul>
<blockquote>
<table border="1">
<caption>Table 126 &mdash; Position type requirements</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">[&hellip;]</th>
</tr>

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

<tr>
<td>
<code>p == q</code>
</td>
<td>
<del>convertible to <code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td>
<code>p != q</code>
</td>
<td>
<del>convertible to <code>bool</code></del><ins><code>BT</code></ins>
</td>
<td>
[&hellip;]
</td>
</tr>

</table>
</blockquote>
</blockquote>
<blockquote>
</blockquote>
</li>

<li><p>Change 32.2.1 <a href="https://wg21.link/thread.req.paramname">[thread.req.paramname]</a> p1 as indicated:</p>

<blockquote>
<p>
-1- Throughout this Clause, the names of template parameters are used to express type requirements. <del>If a template
parameter is named <code>Predicate</code>, <code>operator()</code> applied to the template argument shall return a value that
is convertible to <code>bool</code></del><ins><code>Predicate</code> is a function object type (22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>).
Let <code>pred</code> denote an lvalue of type <code>Predicate</code>. Then the expression <code>pred()</code> shall have a type that meets the 
<code>BooleanTestable</code> requirements ( [booleantestable.requirements]). The return value of <code>pred()</code>, 
converted to <code>bool</code>, yields <code>true</code> if the corresponding test condition is satisfied, and <code>false</code> otherwise</ins>.
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-11-05; Daniel comments]</i></p>

<p>
The paper <a href="https://isocpp.org/files/papers/P2167R3.html">P2167R3</a> has been reviewed and accepted by LWG and would
solve this issue.
</p>

<p><i>[2022-11-22 Resolved by <a href="https://wg21.link/P2167R3" title=" Improved Proposed Wording for LWG 2114 (contextually convertible to bool)">P2167R3</a> accepted in Kona. Status changed: Open &rarr; Resolved.]</i></p>



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






</body>
</html>
