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

2024-11-11


736. Is the & ref-qualifier needed?

Section: 9.3  [dcl.decl]     Status: NAD     Submitter: Alberto Ganesh Barbati     Date: 16 October, 2008

Do we really need the & ref-qualifier? We could get the same behavior without it if we relaxed the restriction on ref-qualified and non-ref-qualified overloads in the same set:

The main objection I can see to this change is that we would lose the notational convenience of the & ref-qualifier, which would need to be replaced by a pair of declarations. We might overcome this by still allowing a single & on a function (although it would not be a ref-qualifier) as a synonym to a non-ref-qualified declaration plus a deleted ref-qualified declaration.

The biggest asymmetry between the implicit object parameter and regular parameters is not in reference binding but in type deduction. Consider:

    template <class R, class C, class A> void f(R (C::*p)(A));

With these members:

    struct S {
       void mv(std::string);
       void mr(std::string&);
       void ml(std::string&&);
    };

then

    f(&S::mv); // deduces A = string
    f(&S::mr); // deduces A = string&
    f(&S::ml); // deduces A = string&&

On the other hand, with these members:

    struct S {
       void mv(std::string);
       void mr(std::string) &;
       void ml(std::string) &&
    };

then

  f(&S::mv); // deduces C = S
  f(&S::mr); // illegal
  f(&S::ml); // illegal

To make template f work with any pointer to member function, I need three overloads of f. Add cv-qualifiers and it's twelve overloads!

And then there is the interaction with concepts. Consider this type:

    struct Value {
        Value& operator=(const Value&) &;
    };

Is it, say, Regular? If so, will the following compile, and what is the outcome?

    template <Regular T> void f() {
      T() = T();
    }

    void g() {
      f<Value>();
    }

If Value is not Regular, that is a good motivation to avoid ever using & ref-qualifiers on operator= (and probably on any member functions).

If Value is Regular, then either f<Value>() doesn't compile, violating one of the principal motivations for concepts, or it calls Value::operator= on an rvalue, which was explicitly prohibited.

Rationale, March, 2009:

The CWG did not feel that the suggested change was a signficant improvement over the existing specification.