Reputation: 47620
Is it possible to create method that will work differently when object *this
is actually a temporary?
For example:
#include <iostream>
struct BigObj{
void changeFast() {}
};
class A {
BigObj obj;
public:
A(){}
A(const A& a) {
obj = a.obj;
std::cout << "copy\n";
}
A(A&& a) {
obj = std::move(a.obj);
std::cout << "move\n";
}
A changed() {
A ret = *this; //(1)
ret.obj.changeFast();
return ret;
}
};
int main(){
A a;
A b = std::move(a).changed();
(void)b;
return 0;
}
In line (1) we have copy but it's not really needed. But we can't always move here because sometimes method called on not-temporary. What should one do to avoid copy here?
If it was not method but just function one may write to similar functions:
A changed(const A& a){
}
A changed(A&& a){
}
Upvotes: 3
Views: 59
Reputation: 153840
You can overload functions on the r-valueness of *this
. For example:
class A
{
public:
// ...
A changed() const&; // called for l-values
A changed() &&; // called for r-values
};
You cannot overload a version without reference qualification with one having reference qualifcations, though. See 13.1 [over.load] paragraph 2, third bullet:
Member function declarations with the same name and the same parameter-type-list as well as member function template declarations with the same name, the same parameter-type-list, and the same template parameter lists cannot be overloaded if any of them, but not all, have a ref-qualifier (8.3.5).
Upvotes: 4
Reputation: 477040
Yes, you need to declare A changed() &&;
. This overload will be available when the instance is an rvalue.
struct A
{
void foo() & { }
void foo() && { }
};
int main()
{
A x;
x.foo(); // picks first overload
std::move(x).foo(); // picks second overload
A().foo(); // "typical" use case for second overload
}
This new language feature may not be supported by all compilers yet.
Upvotes: 3