I wrote this simple test to overload based on whether this
is an rvalue or an lvalue. The original version had addition cases, but I reduced it down the one that’s puzzling me.
#include <iostream>
struct A {
int pp=0;
A(int p) : pp(p) {}
A &prop(int nn) & {pp=nn; return *this;}
A &&prop(int nn) && {pp=nn; return std::move(*this);}
};
struct B {
B(const A &aa) {std::cout << "COPY: " << aa.pp << std::endl;}
B(A &&aa) {std::cout << "MOVE: " << aa.pp << std::endl;}
};
int main() {
A aa(99);
B b4(aa.prop(33).prop(4)); // 4 COPY
std::cout << "4 == " << aa.pp << std::endl;
return 0;
}
The output is what I expected
COPY: 4
4 == 4
So far, so good. Then I modified A
to use a method that deduces this.
struct A {
int pp=0;
A(int p) : pp(p) {}
template <typename self> A prop(this self &&me, int nn) {
me.pp=nn;
return me;
}
};
I expected to get the same result, but I don’t:
MOVE: 4
4 == 33
-
Why does the second version call the move method?
-
Even though it calls the move method, I would still expect to see nn set to 4 and not 33. What’s going on?