I'm new to C++0x and I'm trying to wrap my head around rvalue references and move constructors. I'm using g++ 4.4.6 with -std=c++0x, and I'm confused by the following piece of code:
class Foo { public: Foo() : p( new int(0) ) { printf("default ctor\n"); } Foo( int i ) : p( new int(i) ) { printf("int ctor\n"); } ~Foo() { delete p; printf("destructor\n"); } Foo( const Foo& other ) : p( new int( other.value() ) ) { printf("copy ctor\n"); } Foo( Foo&& other ) : p( other.p ) { printf("move ctor\n"); other.p = NULL; } int value() const { return *p; } private: // make sure these don't get called by mistake Foo& operator=( const Foo& ); Foo& operator=( Foo&& ); int* p; }; Foo make_foo(int i) { // create two local objects and conditionally return one or the other // to prevent RVO Foo tmp1(i); Foo tmp2(i); // With std::move, it does indeed use the move constructor // return i ? std::move(tmp1) : std::move(tmp2); return i ? tmp1 : tmp2; } int main(void) { Foo f = make_foo( 3 ); printf("f.i is %d\n", f.value()); return 0; } I find that as written, the compiler uses the copy constructor build the object in main(). When I use the std::move line inside make_foo(), then the move constructor is used in main(). Why is std::move necessary inside make_foo()? I would think that although tmp1 and tmp2 are named objects inside make_foo(), when they're returned from a function they should become temporaries.
cannot bind Foo lvalue to Foo&&showing that the compiler still sees the return value as an lvalue.deleteto explicitly delete the default assignment operators, instead of just leving them undefined (Foo& operator=( const Foo& ) = delete;). This way you get a compiler error if you try to use them instead of just a linker error.