I can't remember which talk it was, but recently I watched some talks from CppCon 2017 and there someone mentioned as some kind of side-note, that the only true way of overloading operator=
would be in the following fashion:
class test {
public:
test& operator=(const test&) &;
};
He explicitly emphasized the trailing &
but didn't say what it does.
So what does it do?
Best Answer
Ref-qualifiers - introduced in C++11
Ref-qualifiers is not C++17 feature (looking at the tag of the question), but was a feature introduced in C++11.
Note that an rvalue may be used to initialize a const lvalue reference (and in so expanding the lifetime of the object identified by the rvalue), meaning that if we remove the rvalue ref-qualifier overloads from the example above, then the rvalue value categories in the example will all favour the remaining
const &
overload:See e.g. the following blog post for for a brief introduction:
rvalues cannot invoke non-
const
&
overloadsTo possibly explain the intent of your recollected quote from the CppCon talk,
we visit [over.match.funcs]/1, /4 & /5 [emphasis mine]:
From /5 above, the following overload (where the explicit
&
ref-qualifier has been omitted)allows assigning values to r-values, e.g.
However, if we explicitly declare the overload with the
&
ref-qualifier, [over.match.funcs]/5.1 does not apply, and as long we do not supply an overload declared with the&&
ref-qualifier, r-value assignment will not be allowed.I won't place any opinion as to whether explicitly including the
&
ref-qualifier when declaring custom assignment operator overloads is "the only true way of overloadoperator=
", but would I dare to speculate, then I would guess that the intent behind such a statement is the exclusion of to-r-value assignment.As a properly designed assignment operator should arguably never be
const
(const T& operator=(const T&) const &
would not make much sense), and as an rvalue may not be used to initialize a non-const lvalue reference, a set of overloads foroperator=
for a given typeT
that contain onlyT& operator=(const T&) &
will never proviade a viable overload that can be invoked from aT
object identified to be of an rvalue value category.