Title
Meaning of "corresponds" for rewritten operator candidates
Status
open
Section
12.2.2.3 [over.match.oper]
Submitter
Corentin Jabot

Created on 2023-09-15.00:00:00 last changed 6 days ago

Messages

Date: 2023-09-15.00:00:00

Subclause 12.2.2.3 [over.match.oper] paragraph 4 specifies:

A non-template function or function template F named operator== is a rewrite target with first operand o unless a search for the name operator!= in the scope S from the instantiation context of the operator expression finds a function or function template that would correspond (6.4.1 [basic.scope.scope]) to F if its name were operator==, where S is the scope of the class type of o if F is a class member, and the namespace scope of which F is a member otherwise. A function template specialization named operator== is a rewrite target if its function template is a rewrite target.

The meaning of "corresponds" has changed with paper P0847 such that this example from the Working Paper is now ill-formed:

  struct B {
    bool operator==(const B&);
  };
  struct C : B {
    C();
    C(B);
    bool operator!=(const B&);
  };
  bool c1 = B() == C();    // was OK, now ill-formed

The reason is that the definition of "corresponds" now also considers the object parameters, which are different in the example above.

Possible resolution:

  1. Change and split in 6.4.1 [basic.scope.scope] paragraph 3 as follows:

    ...

    Two functions have corresponding non-object signatures if they have the same non-object-parameter-type-list. Two function templates have corresponding non-object signatures if their template-parameter-lists have the same length, their corresponding template-parameter s are equivalent, and they have equivalent non-object-parameter-type-lists and return types (if any), and, if both are non-static members, they have corresponding object parameters. Two functions or function templates have corresponding signatures if they have corresponding non-object signatures and, if both are non-static members, they have corresponding object parameters.

  2. Change in 6.4.1 [basic.scope.scope] paragraph 4 as follows:

    Two declarations correspond if they (re)introduce the same name, both declare constructors, or both declare destructors, unless
    • either is a using-declarator , or
    • one declares a type (not a typedef-name) and the other declares a variable, non-static data member other than of an anonymous union (11.5.2 [class.union.anon]), enumerator, function, or function template, or
    • each declares a function or function template and they do not declare corresponding overloads.
    Two function or function template declarations declare corresponding overloads if:
    • both declare functions with the same non-object-parameter-type-list, equivalent (13.7.7.2 [temp.over.link]) trailing requires-clauses (if any, except as specified in 13.7.5 [temp.friend]), and, if both are non-static members, they have corresponding object parameters, corresponding signatures or both declare function templates with corresponding signatures and equivalent template-heads and trailing requires-clauses (if any).
    • both have equivalent (13.7.7.2 [temp.over.link]) template-heads and trailing requires-clauses (if any, except as specified in 13.7.5 [temp.friend]).
  3. Change in 12.2.2.3 [over.match.oper] paragraph 4 as follows:

    A non-template function or function template F named operator== is a rewrite target with first operand o unless a search for the name operator!= in the scope S from the instantiation context of the operator expression finds a function or function template F2 such that would correspond F and F2 have corresponding non-object signatures (6.4.1 [basic.scope.scope]) to F if its name were operator==, where S is the scope of the class type of o if F is a class member, and the namespace scope of which F is a member otherwise. A function template specialization named operator== is a rewrite target if its function template is a rewrite target.
History
Date User Action Args
2023-09-15 00:00:00admincreate