dabadaba
dabadaba

Reputation: 9512

Expected usage of move constructor not happening

This is my class and my program:

class A {
    public:
        int x;
        int* v;
        A() : x(5), v(new int[5]) {cout<<"default ctor. "; for (int i=0; i<x; i++) v[i]=rand()%10;}
        A(const A& a) : x(a.x), v(new int[x]) {cout<<"copy ctor. "; for (int i=0; i<x; i++) v[i]=a.v[i]; }
        A(A&& a) : x(a.x), v(a.v) {cout<<"move ctor. ";a.x=0;a.v=0;}
        A& f() {return *this;}
        A g() {return *this;}
};

int main() {
    srand(time(0));
    cout<<"A a --> ";A a;cout<<endl;
    cout<<"A b(A()) --> ";A b(A());cout<<endl;
    cout<<"A c(a.f()) --> ";A c(a.f());cout<<endl;
    cout<<"A d(a.g()) --> ";A d(a.g());cout<<endl;
    cout<<"A e(A().g()) --> ";A e(A().g());cout<<endl;
}

I would expect the objects b, d and e to use the move constructor, however the output I get is:

A a --> default ctor.

A b(A()) -->

A c(a.f()) --> copy ctor.

A d(a.g()) --> copy ctor.

A e(A().g()) --> default ctor. copy ctor.

If in all three cases r-values are the arguments of the constructors, why isn't the move constructor being used?

Obviously I am compiling with the -std=c++11 option.

Upvotes: 1

Views: 75

Answers (1)

With b, you've hit the "most vexing parse." b is a function declaration, not an object.

Take the expression

A b(A());

Let's do some name changes and semantic-preserving transformations:

int foo(int (*p)());

Now, I think it's pretty clear that foo is a function (returns int and takes pointer to int() function as parameter). Now substitute back A for int, b for foo and remember functions get implicitly converted to pointer-to-function. You'll see it's the same thing.

To get around this, you can use brace initialisation (thanks to @MikeSeymour for pointing that out):

A b{A()};

With d, I think you're the "victim" of copy elision. The "copy ctor" output is probably from initialising the return value with *this; the move from the return value to d is completely elided.

With e, it's the same story as d.

Upvotes: 4

Related Questions