views:

59

answers:

4

Given class:

class C
{
public:
    C()
    {
        cout << "Dflt ctor.";
    }
    C(C& obj)
    {
        cout << "Copy ctor.";
    }
    C(C&& obj)
    {
        cout << "Move ctor.";
    }
    C& operator=(C& obj)
    {
        cout << "operator=";
        return obj;
    }
    C& operator=(C&& obj)
    {
        cout << "Move operator=";
        return obj;
    }
};

and then in main:

int _tmain(int argc, _TCHAR* argv[])
{
    C c;
    C d = c;
    C e;
    e = c;
    return 0;
}

as you will see from the output there are "regular" ver. of cpy ctor and = optor invoked but not those with rvalue args. So I would like to ask in what circumstances move ctor and operator=(C&&) will be invoked?
Thank you.

+6  A: 

The move constructor will be invoked when the right-hand side is a temporary, or something that has been explicitly cast to C&& either using static_cast<C&&> or std::move.

C c;
C d(std::move(c)); // move constructor
C e(static_cast<C&&>(c)); // move constructor
C f;
f=std::move(c); // move assignment
f=static_cast<C&&>(c); // move assignment
C g((C())); // move construct from temporary (extra parens needed for parsing)
f=C(); // move assign from temporary
Anthony Williams
+1  A: 

IIRC, you have to use C d = std::move(c) to use the move constructor.

An example not tested but that could explain better the use of move constructor :

C&& foo() { C c; return std::move(c); }
Scharron
+1  A: 
std::swap(c,e); // c and e variables declared in your _tmain()

would call the move constructor.

Stephane Rolland
+1  A: 

All of your variables are lvalues and thus cannot be moved implicitly, since you may need to access them later. In addition, copy constructors and assignment operators take const references.

Rvalue references work on, well, rvalues, that is, temporary objects. In order to see the move constructor used, first, you will have to actually create a temporary object. In addition, don't forget that RVO still applies and may well nail any or all of your std::cout calls.

You can create an rvalue from an lvalue using std::move(lvalue).

DeadMG