CWG Issue 2586 (original) (raw)

This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-11-07


2586. Explicit object parameter for assignment and comparison

Section: 11.10.1 [class.compare.default]Status: CD6Submitter: Barry RevzinDate: 2022-05-07Liaison: EWG

[Accepted at the July, 2022 meeting.]

"Deducing this" allows to declare assignment and comparison operator functions as explicit object member functions.

However, such an assignment operator can never be a copy or move assignment operator, which means it always conflicts with the implicitly-defined one:

struct C { C& operator=(this C&, C const&); // error: can't overload with the copy assignment operator };

Similarly, operator== or operator<=> can be declared with an explicit object parameter, but they cannot be defaulted:

struct D { bool operator==(this D const&, D const&) = default; // error: not a kind of comparison that can be defaulted };

There seems to be no reason to disallow that, for people who prefer writing all of their members with explicit object parameters.

Suggested resolution [SUPERSEDED]:

  1. Change in 11.4.6 [class.copy.assign] paragraph 1 as follows:

    A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly onenon-object parameter of type X, X&, const X&, volatile X&, or const volatile X&.

  2. Change in 11.4.6 [class.copy.assign] paragraph 3 as follows:

    A user-declared move assignment operator X::operator= is a non-static non-template member function of class X with exactly one non-object parameter of type X&&, const X&&, volatile X&&, or const volatile X&&.

  3. Change in 11.10.1 [class.compare.default] paragraph 1 as follows:

    A defaulted comparison operator function (12.4.3 [over.binary]) for some class C shall be a non-template function that is

    • a non-static const non-volatile member of C having one parameter of type const C& and either no ref-qualifier or the ref-qualifier &, or or friend of C and
    • a friend of C having either has two parameters of type const C& or two parameters of type C , where the implicit object parameter (if any) is considered to be the first parameter..

Additional notes (May, 2022):

Forwarded to EWG withpaper issue 1235, by decision of the CWG chair.

Approved by EWG telecon 2022-06-09 and EWG 2022-06 electronic poll.

Seevote.

Additional notes (July, 2022):

The suggested resolution makes the following a copy assignment operator, suppressing the implicitly-declared one, which is surprising:

struct B { B &operator =(this int, const B &); // copy assignment operator };

Proposed resolution (approved by CWG 2022-07-15):

  1. Change in 9.6.2 [dcl.fct.def.default] paragraph 2 as follows:

    The type T1 of an An explicitly defaulted special member function F F1 with type T1 is allowed to differ from thecorresponding special member function F2 withtype T2 it would have had if it were that would have been implicitly declared, as follows:

    • T1 and T2 may have differing _ref-qualifier_s;
    • if F2 has an implicit object parameter of type "reference to C", F1 may be an explicit object member function whose explicit object parameter is of type "reference to C";
    • T1 and T2 may have differing exception specifications; and
    • if T2 F2 has a non-objectparameter of type const C&, the corresponding non-object parameter of T1 F1 may be of type C&.
      If T1 differs from T2 in any other away other than as allowed by the preceding rules, then:
    • if F F1 is an assignment operator, and the return type of T1 differs from the return type of T2 orT1 F1's non-object parameter type is not a reference, the program is ill-formed;
    • otherwise, if F F1 is explicitly defaulted on its first declaration, it is defined as deleted;
    • otherwise, the program is ill-formed.
  2. Change in 11.4.6 [class.copy.assign] paragraph 1 as follows:

    A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly onenon-object parameter of type X, X&, const X&, volatile X&, or const volatile X&.

  3. Change in 11.4.6 [class.copy.assign] paragraph 3 as follows:

    A user-declared move assignment operator X::operator= is a non-static non-template member function of class X with exactly one non-object parameter of type X&&, const X&&, volatile X&&, or const volatile X&&.

  4. Change in 11.10.1 [class.compare.default] paragraph 1 as follows:

    A defaulted comparison operator function (12.4.3 [over.binary]) for some class C shall be a non-template function that is

    • a non-static const non-volatile member of C having one parameter of type const C& and either no ref-qualifier or the ref-qualifier &, or or friend of C and
    • a friend of C having either has two parameters of type const C& or two parameters of type C , where the implicit object parameter (if any) is considered to be the first parameter..