Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofResolved status.

2114. Incorrect "contextually convertible tobool" requirements

Section: 16.4.4.4[nullablepointer.requirements], 24.3.5.3[input.iterators], 24.3.5.7[random.access.iterators], 26.1[algorithms.general], 26.8[alg.sorting], 32.2.1[thread.req.paramname]Status:ResolvedSubmitter: Daniel KrüglerOpened: 2011-12-09Last modified: 2025-03-13

Priority:3

View all otherissues in [nullablepointer.requirements].

View all issues withResolved status.

Discussion:

As of 16.4.4.2[utility.arg.requirements] Table 17/18, the return types of the expressions

a == b

or

a < b

for types satisfying theEqualityComparable orLessThanComparabletypes, respectively, are required to be "convertible tobool" which corresponds toa 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 "contextually convertible tobool" instead, which corresponds to a direct-initialization context (In addition to "normal" direct-initialization constructions, operands of logical operations as well asif orswitch conditions also belong to this special context).

One example for these new requirements are input iterators which satisfyEqualityComparable but also specify that the expression

a != b

shall be just "contextually convertible tobool". The same discrepancy exists for requirement setNullablePointer in regard to several equality-related expressions.

For random access iterators we have

a < b contextually convertible tobool

as well as for all derived comparison functions, so strictly speaking we could have a random access iterator that does not satisfy theLessThanComparable requirements, which looks like anartifact to me.

Even if we keep with the existing requirements based onLessThanComparable orEqualityComparable 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[unique.ptr.special] p3:

template <class T1, class D1, class T2, class D2>bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

-3-Returns:x.get() != y.get().

Similar examples exist in 20.3.1.3.3[unique.ptr.single.dtor] p2, 20.3.1.3.4[unique.ptr.single.asgn] p9,20.3.1.3.5[unique.ptr.single.observers] p1+3+8, etc.

In all these places the expressions involving comparison functions (butnot those of the conversion of aNullablePointer tobool!) assume to be "convertible tobool". I think thisis a very natural assumption and all delegations of the comparison functions of some typeX to someother API typeY in third-party code does so assuming that copy-initialization semantics willjust work.

The actual reason for using the newer terminology can be rooted back to LWG556(i). My hypotheses is that the resolution of that issue also needs a slight correction. Why so?

The reason for opening that issue were worries based on the previous "convertible tobool"wording. An expressions like "!pred(a, b)" might not be well-formed in those situations, becauseoperator! might not be accessible or might have an unusual semantics (and similarly for other logicaloperations). This can indeed happen with unusual proxy return types, so the idea was that the evaluation ofPredicate,BinaryPredicate (26.1[algorithms.general] p8+9), andCompare (26.8[alg.sorting] p2) should be defined based on contextual conversion tobool. Unfortunately thisalone is not sufficient: In addition, I think, wealso want the predicates to be (implicitly) convertible tobool! Without this wording, several conditions are plain wrong, e.g. 26.6.6[alg.find] p2, which talks about "pred(*i) != false" (find_if) and "pred(*i) == false" (find_if_not). These expressions are not within a boolean context!

While we could simply fix all these places by proper wording to be considered in a "contextual conversion tobool", I think that this is not the correct solution: Many third-party libraries already refer tothe previous C++03Predicate definition — it actually predates C++98 and is as old as theSGI specification. It seems to be a high price topay to switch to direct initialization here instead of fixing a completely different specification problem.

A final observation is that we have another definition for aPredicate in 32.2.1[thread.req.paramname] p2:

If a parameter isPredicate,operator() applied to the actual template argument shall return a value thatis convertible tobool.

The problem here is not that we have two different definitions ofPredicate in the standard — 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, becauseoperator() is not defined in a strict sense. But the actually worse second problem is that this wording has the verysame problem that has originally lead toLWG556(i)! We only need to look at 32.7.4[thread.condition.condvar] p15 to recognice this:

while (!pred())  wait(lock);

The negation expression here looks very familiar to the example provided in LWG556(i) and is sensitiveto the same "unusual proxy" problem. Changing the 32.2.1[thread.req.paramname] wording to a corresponding"contextual conversion tobool" wouldn't work either, because existing specifications rely on "convertibletobool", e.g. 32.7.4[thread.condition.condvar] p32+33+42 or 32.7.5[thread.condition.condvarany] p25+26+32+33.

To summarize: I believe that LWG556(i) was not completely resolved. A pessimistic interpretation is,that even with the current wording based on "contextually convertible tobool" the actual problem of that issue hasnot been fixed. What actually needs to be required here is some normative wording that basicallyexpresses something along the lines of:

The semantics ofany contextual conversion tobool shall be equivalent to the semantics of any implicit conversion tobool.

This is still not complete without having concepts, but it seems to be a better approximation. Another way of solvingthis issue would be to define a minimum requirements table with equivalent semantics. The proposed wording is a bitsimpler but attempts to express the same thing.

[2012, Kona]

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 outchanges to section 30.

Move to open, and then to Review when updated wording from Stefan is available.

[2012-10-12, STL comments]

  1. 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 tobool, 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:

    1. Standard Library implementations would have to go to great lengths to respect such wacky types, essentially usingstatic_cast<bool> when invoking any predicates or comparators.

    2. Otherwise, such wacky types would be de facto nonportable, because they would make Standard Library implementations explode.

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

    if (pred(args))if (!pred(args))if (cond && pred(args))if (cond && !pred(args))

    These are real examples taken from Dinkumware's implementation. There are others that would be realistic ("pred(args) && cond", "cond || pred(args)", etc.)

    Although negation was mentioned in this issue's Discussion section, and in LWG556(i)'s, the current proposed resolution doesn't fix this problem. Requiringpred(args) to be implicitly and contextually convertible tobool doesn't preventoperator!() from being overloaded and returningstd::string (as a wacky example). More ominously, it doesn't preventoperator&&() andoperator||() from being overloaded and destroying short-circuiting.

  2. 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:

    1. Introduce a new "concept" in 16.4.4[utility.requirements], which I would callBooleanTestable in the absence of better ideas.

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

    3. 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:

      1. Given aBooleanTestable x,x is both implicitly and contextually convertible tobool.

      2. Given aBooleanTestable x,!x isBooleanTestable. (This is intentionally "recursive".)

      3. Given aBooleanTestable x,bool t = x, t2(x), f = !x; has the postconditiont == t2 && t != f.

      4. Given aBooleanTestable x and aBooleanTestable y of possibly different types, "x && y" and "x || y" invoke the built-inoperator&&() andoperator||(), triggering short-circuiting.

      5. bool isBooleanTestable.

    I believe that this simultaneously gives users great latitude to use types other thanbool, 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.)

  3. 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 "explicit operator bool()" and "operator int()", which might behave differently (or be deleted, etc.).

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

  5. 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 withbool"), and provides a "base case" for requirement (IV) that may or may not be necessary. Sincebool isBooleanTestable, overloadingoperator&&(bool, Other) (etc.) clearly makes theOther type non-BooleanTestable.

Previous resolution from Daniel [SUPERSEDED]:

This wording is relative to the FDIS.

  1. Change Table 25 — "NullablePointer requirements" in 16.4.4.4[nullablepointer.requirements]as indicated:

    Table 25 —NullablePointer requirements
    ExpressionReturn typeOperational semantics
    […]
    a != bcontextually convertible tobool!(a == b)
    a == np
    np == a
    contextually convertible toboola == P()
    a != np
    np != a
    contextually convertible tobool!(a == np)
  2. Change Table 107 — "Input iterator requirements" in 24.3.5.3[input.iterators]as indicated:

    Table 107 — Input iterator requirements (in addition to Iterator)
    ExpressionReturn typeOperational semanticsAssertion/note
    pre-/post-condition
    a != bcontextually convertible tobool!(a == b)pre:(a, b) is in the domain of==.
    […]
  3. Change Table 111 — "Random access iterator requirements" in 24.3.5.7[random.access.iterators]as indicated:

    Table 111 — Random access iterator requirements (in addition to bidirectional iterator)
    ExpressionReturn typeOperational semanticsAssertion/note
    pre-/post-condition
    […]
    a < bcontextually convertible toboolb - a > 0< is a total ordering relation
    a > bcontextually convertible toboolb < a> is a total ordering relation opposite to<.
    a >= bcontextually convertible tobool!(a < b)
    a <= bcontextually convertible tobool!(a > b)
  4. Change 26.1[algorithms.general] p8+9 as indicated:

    -8- ThePredicate parameter is used whenever an algorithm expects a function object (22.10[function.objects]) that, when applied to the result of dereferencing the corresponding iterator, returns a value testable astrue. In other words, if an algorithm takesPredicate pred as its argument and first as its iterator argument, it should work correctly in the constructpred(*first)implicitly or contextually converted tobool (Clause 7.3[conv]). The function objectpred shall not apply any non-constant function through the dereferenced iterator.

    -9- TheBinaryPredicate parameter is used whenever an algorithm expects a function object that when appliedto the result of dereferencing two corresponding iterators or to dereferencing an iterator and typeT whenT is part of the signature returns a value testable astrue. In other words, if an algorithm takesBinaryPredicate binary_pred as its argument andfirst1 andfirst2 as its iterator arguments, it shouldwork correctly in the constructbinary_pred(*first1, *first2)implicitly or contextually converted tobool (Clause 7.3[conv]).BinaryPredicate always takes the first iterator'svalue_type as its first argument, that is, in those caseswhenT value is part of the signature, it should work correctly in the constructbinary_pred(*first1, value)implicitly or contextually converted tobool (Clause 7.3[conv]).binary_pred shall not apply any non-constant function through the dereferenced iterators.

  5. Change 26.8[alg.sorting] p2 as indicated:

    -2-Compare is a function object type (22.10[function.objects]). The return value of the function call operation applied to an object of typeCompare, whenimplicitly or contextually converted tobool (7.3[conv]), yieldstrue if the first argument of the call is less than the second, andfalse otherwise.Compare comp is used throughout for algorithms assuming an ordering relation. It is assumed thatcomp will not apply any non-constant function through the dereferenced iterator.

  6. Change 32.2.1[thread.req.paramname] p2 as indicated:

    -2-If a parameter isPredicate, operator() applied to the actual template argument shall return a value thatis convertible toboolPredicate is a function object type (22.10[function.objects]).The return value of the function call operation applied to an object of typePredicate, when implicitly or contextually converted tobool (7.3[conv]), yieldstrue if the corresponding test condition issatisfied, andfalse otherwise.

[2014-05-20, Daniel suggests concrete wording based on STL's proposal]

The presented wording follows relatively closely STL's outline with the following notable exceptions:

  1. A reference toBooleanTestable in table "Return Type" specifications seemed very unusual to me andI found no "prior art" for this in the Standard. Instead I decided to follow the usual style to add a symbolwith a specific meaning to a specific paragraph that specifies symbols and their meanings.

  2. STL's requirement IV suggested to directly refer to built-in operators&& and||. In myopinion this concrete requirement isn't needed if we simply require that twoBooleanTestable operands behave equivalently to two those operands after conversion tobool (each of them).

  3. I couldn't find a good reason to require normatively that typebool meets the requirements ofBooleanTestable: Myassertion is that after having defined them, the result simply falls out of this. But to make this a bit clearer, I addedalso a non-normative note to these effects.

[2014-06-10, STL comments]

In the current wording I would like to see changed the suggested changes described by bullet #6:

  1. In 23.2.2[container.requirements.general] p4 undo the suggested change

  2. Then change the 7 occurrences of "convertible tobool" in the denoted tables to "bool".

[2015-05-05 Lenexa]

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

[2015-07 Telecon]

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

[2016-02-27, Daniel updates wording]

  1. The revised wording has been updated from N3936 to N4567.

  2. 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 tobool" and "can be implicitly converted tobool. 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:

    2016-08-07, Daniel: The below example has been corrected to reduce confusion about the performed conversions as indicatedby the delta markers:

    using Bool = int;struct OddBoolean {  explicitoperator bool() const = delete;  operator Bool() const;OddBoolean(bool) = delete;  OddBoolean(Bool){}}ob;bool b2 = ob; // OKbool b1(ob);  // ErrorOddBoolean b2 = true; // OKOddBoolean b1(true);  // Error
  3. In [booleantestable.requirements] a note has been added to ensure that an implementation is not allowed to break any short-circuiting semantics.

  4. I decided to separate LWG2587(i)/2588(i) from this issue. Both these issues aren't exactly thesame but depending on the committee's position, their resolution might benefit from the new vocabulary introducedhere.

[2021-06-25; Daniel comments]

The paperP2167R1 is provided to resolve this issue.

[2022-05-01; Daniel comments]

The paperP2167R2 is provided to resolve this issue.

Previous resolution [SUPERSEDED]:

This wording is relative to N4567.

  1. Change 16.4.4.2[utility.arg.requirements] p1, Table 17 — "EqualityComparable requirements", andTable 18 — "LessThanComparable requirements" as indicated:

    -1- […] In these tables,T is an object or reference type to be supplied by a C++ programinstantiating a template;a,b, andc are values of type (possiblyconst)T;s andt are modifiable lvalues of typeT;u denotes an identifier;rv is an rvalue of typeT;andv is an lvalue of type (possiblyconst)T or anrvalue of typeconst T; andBT denotes a type that meets theBooleanTestable requirements ([booleantestable.requirements]).

    […]

    Table 17 —EqualityComparable requirements [equalitycomparable]
    ExpressionReturn typeRequirement
    a == bconvertible to
    bool
    BT
    == is an equivalence relation, that is, it has thefollowing properties: […]

    […]

    Table 18 —LessThanComparable requirements [lessthancomparable]
    ExpressionReturn typeRequirement
    a < bconvertible to
    bool
    BT
    < is a strict weak ordering relation (26.8[alg.sorting])
  2. Between 16.4.4.3[swappable.requirements] and 16.4.4.4[nullablepointer.requirements] insert a new sub-clause as indicated:

    ?.?.?.?BooleanTestable requirements [booleantestable.requirements]

    -?- ABooleanTestable type is a boolean-like type that also supports conversions tobool.A typeB meets theBooleanTestable requirements if the expressions described in Table ?? are valid and have the indicated semantics, and ifB also satisfies all the other requirements of this sub-clause [booleantestable.requirements].

    An objectb of typeB can be implicitly converted tobool and in addition can be contextually converted tobool (Clause 4). The result values of both kinds of conversions shall be equivalent.

    [Example: The typesbool,std::true_type, andstd::bitset<>::reference areBooleanTestable types. —end example]

    For the purpose of Table ??, letB2 andBn denote types (possibly both equal toB or to each other) that meet theBooleanTestable requirements, letb1 denote a (possiblyconst) value ofB, letb2 denote a (possiblyconst) value ofB2, and lett1 denote a value of typebool.

    [Note: These rules ensure what an implementation can rely on but doesn't grant itlicense to break short-circuiting behavior of aBooleanTestable type. —end note]

  3. Somewhere within the new sub-clause [booleantestable.requirements] insert the following new Table (?? denotesthe assigned table number):

    Table ?? —BooleanTestable requirements [booleantestable]
    ExpressionReturn typeOperational semantics
    bool(b1)boolRemarks:bool(b1) == t1 for every value
    b1 implicitly converted tot1.
    !b1BnRemarks:bool(b1) == !bool(!b1) for
    every valueb1.
    b1 && b2boolbool(b1) && bool(b2)
    b1 || b2boolbool(b1) || bool(b2)
  4. Change 16.4.4.4[nullablepointer.requirements] p5 and Table 25 — "NullablePointer requirements" as indicated:

    […]

    -5- In Table 25,u denotes an identifier,t denotes a non-const lvalue of typeP,a andb denote values of type (possiblyconst)P,andnp denotes a value of type (possiblyconst)std::nullptr_t, andBT denotes a type that meets theBooleanTestable requirements ([booleantestable.requirements]).

    […]

    Table 25 —NullablePointer requirements [nullablepointer]
    ExpressionReturn typeOperational semantics
    a != bcontextually convertible toboolBT[…]
    a == np
    np == a
    contextually convertible toboolBT[…]
    a != np
    np != a
    contextually convertible toboolBT[…]
  5. Change 22.4.9[tuple.rel] as indicated;

    template<class... TTypes, class... UTypes>constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

    -1-Requires: For alli, where0 <= i andi < sizeof...(TTypes),get<i>(t) == get<i>(u) is a valid expression returning a type thatis convertible toboolmeets theBooleanTestable requirements ([booleantestable.requirements]).sizeof...(TTypes) == sizeof...(UTypes).

    […]

    template<class... TTypes, class... UTypes>constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

    -4-Requires: For alli, where0 <= i andi < sizeof...(TTypes),get<i>(t) < get<i>(u) andget<i>(u) < get<i>(t) are valid expressions returning types thatare convertible toboolmeet theBooleanTestable requirements ([booleantestable.requirements]).sizeof...(TTypes) == sizeof...(UTypes).

    […]

  6. Change 23.2.2[container.requirements.general], Table 95 — "Container requirements", andTable 97 — "Optional container operations" as indicated:

    -4- In Tables 95, 96, and 97X denotes a container class containing objects of typeT,a andb denote values of typeX,u denotes an identifier,r denotes a non-const value of typeX,andrv denotes a non-const rvalue of typeX, andBT denotes a type that meets theBooleanTestable requirements ([booleantestable.requirements]).

    Table 95 — Container requirements
    ExpressionReturn type[…]
    a == bconvertible to
    bool
    BT
    […]
    a != bconvertible to
    bool
    BT
    […]
    a.empty()convertible to
    bool
    BT
    […]

    […]

    Table 97 — Optional container requirements
    ExpressionReturn type[…]
    a < bconvertible to
    bool
    BT
    […]
    a > bconvertible to
    bool
    BT
    […]
    a <= bconvertible to
    bool
    BT
    […]
    a >= bconvertible to
    bool
    BT
    […]
  7. Change 24.3.1[iterator.requirements.general], Table 106 — "Input iterator requirements", andTable 110 — "Random access iterator requirements" as indicated:

    -12- In the following sections,a andb denote values of typeX orconst X,difference_type andreference refer to the typesiterator_traits<X>::difference_type anditerator_traits<X>::reference, respectively,n denotes a value ofdifference_type,u,tmp, andm denote identifiers,r denotes a value ofX&,t denotesa value of value typeT,o denotes a value of some type that is writable to the output iterator, andBT denotes a type that meets theBooleanTestable requirements ([booleantestable.requirements]).

    Table 106 — Input iterator requirements
    ExpressionReturn type[…]
    a != bcontextually convertible to
    bool
    BT
    […]

    […]

    Table 110 — Random access iterator requirements
    ExpressionReturn type[…]
    a < bcontextually convertible to
    bool
    BT
    […]
    a > bcontextually convertible to
    bool
    BT
    […]
    a >= bcontextually convertible to
    bool
    BT
    […]
    a <= bcontextually convertible to
    bool
    BT
    […]
  8. Change 26.1[algorithms.general] p8+p9 as indicated:

    [Drafting note: 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 asadjacent_find,search_n,unique, andunique_copy are not correctly described (because they have no iterator argument namedfirst1), which could give raise to a new library issue. —end drafting note]

    -8- ThePredicate parameter is used whenever an algorithm expects a function object (20.9) that, when appliedto the result of dereferencing the corresponding iterator, returns a value testable astrue.In other words,iIf an algorithm takesPredicate pred as its argument andfirst as its iterator argument,it should work correctly in the constructpred(*first) contextually converted tobool (Clause 4)the expressionpred(*first) shall have a type that meets theBooleanTestable requirements ( [booleantestable.requirements]). The function objectpred shall not apply any non-constant function throughthe dereferenced iteratorits argument.

    -9- TheBinaryPredicate parameter is used whenever an algorithm expects a function object that when appliedto the result of dereferencing two corresponding iterators or to dereferencing an iterator and typeT whenT is part of the signature returns a value testable astrue.In other words, iIf an algorithm takesBinaryPredicate binary_pred as its argument andfirst1 andfirst2 as its iterator arguments,it should work correctly in the constructbinary_pred(*first1, *first2) contextually converted tobool (Clause 4)the expressionbinary_pred(*first1, *first2) shall have a type that meets theBooleanTestable requirements ( [booleantestable.requirements]).BinaryPredicate always takes the first iterator'svalue_type as its first argument, that is, in those cases whenT value is part of the signature,it should work correctly in the constructbinary_pred(*first1, value) contextually converted tobool (Clause 4)the expressionbinary_pred(*first1, value) shall have a type that meets theBooleanTestable requirements ( [booleantestable.requirements]).binary_pred shall not apply any non-constant function throughthe dereferenced iteratorsany of its arguments.

  9. Change 26.8[alg.sorting] p2 as indicated:

    […]

    -2-Compare is a function object type (20.9).The return value of the function call operation applied to an object of typeCompare, when contextually converted tobool(Clause 4), yieldstrue if the first argument of the call is less than the second, andfalse otherwise.Compare comp is used throughout for algorithms assuming an ordering relation.Leta andb denote two argument values whose types depend on the corresponding algorithm. Then the expressioncomp(a, b) shall have a type that meets theBooleanTestable requirements ( [booleantestable.requirements]).The return value ofcomp(a, b), converted tobool, yieldstrue if the first argumenta is less than the second argumentb, andfalse otherwise. It is assumed thatcomp will not apply any non-constant function throughthe dereferenced iteratorany of its arguments.

    […]

  10. Change 31.5.3.3[fpos.operations] and Table 126 — "Position type requirements" as indicated:

    -1- Operations specified in Table 126 are permitted. In that table,

    • P refers to an instance offpos,

    • […]

    • o refers to a value of typestreamoff,

    • BT refers to a type that meets theBooleanTestable requirements ([booleantestable.requirements]),

    • […]

    Table 126 — Position type requirements
    ExpressionReturn type[…]
    p == qconvertible toboolBT[…]
    p != qconvertible toboolBT[…]
  11. Change 32.2.1[thread.req.paramname] p1 as indicated:

    -1- Throughout this Clause, the names of template parameters are used to express type requirements.If a templateparameter is namedPredicate,operator() applied to the template argument shall return a value thatis convertible toboolPredicate is a function object type (22.10[function.objects]).Letpred denote an lvalue of typePredicate. Then the expressionpred() shall have a type that meets theBooleanTestable requirements ( [booleantestable.requirements]). The return value ofpred(), converted tobool, yieldstrue if the corresponding test condition is satisfied, andfalse otherwise.

[2022-11-05; Daniel comments]

The paperP2167R3 has been reviewed and accepted by LWG and wouldsolve this issue.

[2022-11-22 Resolved byP2167R3 accepted in Kona. Status changed: Open → Resolved.]

Proposed resolution:


[8]ページ先頭

©2009-2026 Movatter.jp