Similarly to this
cv-qualifiers, we can also apply ref-qualifiers to *this
. Ref-qualifiers are used to choose between normal and rvalue reference semantics, allowing the compiler to use either copy or move semantics depending on which are more appropriate, and are applied to *this
instead of this
.
Note that despite ref-qualifiers using reference syntax, this
itself is still a pointer. Also note that ref-qualifiers don't actually change the type of *this
; it's just easier to describe and understand their effects by looking at them as if they did.
struct RefQualifiers {
std::string s;
RefQualifiers(const std::string& ss = "The nameless one.") : s(ss) {}
// Normal version.
void func() & { std::cout << "Accessed on normal instance " << s << std::endl; }
// Rvalue version.
void func() && { std::cout << "Accessed on temporary instance " << s << std::endl; }
const std::string& still_a_pointer() & { return this->s; }
const std::string& still_a_pointer() && { this->s = "Bob"; return this->s; }
};
// ...
RefQualifiers rf("Fred");
rf.func(); // Output: Accessed on normal instance Fred
RefQualifiers{}.func(); // Output: Accessed on temporary instance The nameless one
A member function cannot have overloads both with and without ref-qualifiers; the programmer has to choose between one or the other. Thankfully, cv-qualifiers can be used in conjunction with ref-qualifiers, allowing const
correctness rules to be followed.
struct RefCV {
void func() & {}
void func() && {}
void func() const& {}
void func() const&& {}
void func() volatile& {}
void func() volatile&& {}
void func() const volatile& {}
void func() const volatile&& {}
};