Is there a way for a member function to know if the object is an rvalue or lvalue?

Viewed 80

My usecase is I have a class X which has a member function that returns a modified copy of X. Some of these member functions might be stacked like this

X X_before{init};
X X_after = X_before.op_1().op_2().op_3();

In the above code op_1 would create a copy. Now what I am thinking is that there's really no reason why op_2 and op_3 should also need to create a new copy, since X_before.op_1() is now an rvalue. Is there a way that I could achieve this in current C++? I am using C++14, but would also be interested to know if this is possible in later versions.

1 Answers

Since C++11 we have ref-qualified member functions, with that overload resolution could select the appropriate overloading based on the object to be called on is lvalue or rvalue.

#include <iostream>
struct S {
    void f() & { std::cout << "lvalue\n"; }
    void f() &&{ std::cout << "rvalue\n"; }
};
 
int main(){
    S s;
    s.f();            // prints "lvalue"
    std::move(s).f(); // prints "rvalue"
    S().f();          // prints "rvalue"
}
Related