When called, each member function has an implicit object parameter that *this
references.
So (a) these normal function overloads:
void f(const T&);
void f(T&&);
when called like f(x)
; and (b) these member function overloads:
struct C
{
void f() const &;
void f() &&;
};
when called like x.f()
- both (a) and (b) dispatch with similar viability and ranking.
So the use cases are essentially the same. They are to support move semantic optimization. In the rvalue member function you can essentially pillage the objects resources because you know that it is an expiring object (is about to be deleted):
int main()
{
C c;
c.f(); // lvalue, so calls lvalue-reference member f
C().f(); // temporary is prvalue, so called rvalue-reference member f
move(c).f(); // move changes c to xvalue, so again calls rvalue-reference member f
}
So for example:
struct C
{
C operator+(const C& that) const &
{
C c(*this); // take a copy of this
c += that;
return c;
}
C operator+(const C& that) &&
{
(*this) += that;
return move(*this); // moving this is ok here
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…