This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-11-05
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:
| with the & ref-qualifier | without the & ref-qualifier |
struct S {
void f();
};
|
struct S {
void f();
};
|
struct S {
void f() &;
};
|
struct S {
void f();
void f() && = delete;
};
|
struct S {
void f() &&;
};
|
struct S {
void f() &&;
};
|
struct S {
void f() &;
void f() &&;
};
|
struct S {
void f();
void f() &&;
};
|
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.