Question

I am trying to test RVO and rvalue reference. Here is the code:

#include <iostream>

using namespace std;

class B{
public:
    int i;

    B(){
        i = 0;
        cout << "B() " << i << endl;
    }

    B(const B& b){
        i = 1;
        cout << "B(const B&) " << i << endl;
    }

    B(const B&& b){//if remove this constructor, then call B(const B& b)
        i = 2;
        cout << "B(const B&&) " << i << endl;
    }

    ~B(){
        cout << "~B() " << i << endl;
    }
};

B f(){
    B b;
    return b;
}

int main(){

    B b = f();

    return 0;
}

The output is:

B() 0
B(const B&&) 2
~B() 0
~B() 2

Environment: WIN8, Visual Studio 2012 Express

This means that the move constructor: B(const B&&) is called. Two issues raised:

  • Why RVO is not applied here?
  • Why NOT call the copy constructor: B(const B&)?
  • If I remove the B(const B&&), then B(const B&) is called. Weird output:

    B() 0
    B(const B&) 1
    ~B() 0
    ~B() 1

Here are references I found:


EDIT:
The move constructor should be B(B&&). The thing is why move constructor is called NOT the copy constructor.

Était-ce utile?

La solution

Why RVO is not applied here?

It's not simply performing optimizations. g++ does use RVO here when using -O2. You should enable optimizations on your compiler to test this out. However, note that even if RVO might be applied by some compilers, it's not mandatory, so you might see different results using different compilers.

Why NOT call the move constructor: B(const B&)?

That is a copy constructor. It's calling the move constructor which is a better match here.

If I remove the B(const B&&), then B(const B&) is called. Weird!

No, it's not weird. The move constructor will not be implicitly defined by the compiler if you define a copy constructor. Therefore, the compiler is picking the copy constructor, since no move constructor is available.

Note that your move constructor should take a non const rvalue reference:

B(B&& b) {
    // ...
}

Otherwise, you'd just end up doing the same as in the copy constructor.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top