dimanche 5 avril 2015

Why copy constructor is called instead of move constructor?

please look at the following example code:



#include <iostream>

struct Foo {
Foo() { std::cout << "Default!\n"; }
Foo(const Foo& foo) { std::cout << "Copy!\n"; }
Foo(Foo&& foo) { std::cout << "Move!\n"; }
};

struct Bar {
Foo foo;
Bar() {}
Bar(Bar &that) : foo(that.foo) {}
Bar(Bar &&that) : foo(std::move(that.foo)) {}
};

Bar f() {
Bar bar;
return bar;
}

int main() {
Bar bar(f());
}


I'am expecting that the output of this code should be:



Default!
Move!


but what I get is:



Default!
Copy!


I can't see any reason why the copy constructor is called instead of the move constructor. If I put the keyword const in front of Bar &that in the declaration of the copy constructor of struct Bar, I've got the right result. I know that it is better for many cases to take a const lvalue reference rather than just an lvalue reference for copy constructors, but I just want to know the reason why this phenomenon have been occurred.


Why in this example Bar & has been preferred over Bar && even though the return value of f() should be considered as a prvalue? Why the keyword const solves the problem? Does const really solves the problem? Does it have something to do with RVO (Return Value Optimization)? Or, is this just a compiler bug?


I've tested this example on Visual C++ November 2012 CTP.


I've found a similar issue here:


Copy constructor is being called instead of the move constructor


But I still can't understand why.


Does anyone can help me?


Aucun commentaire:

Enregistrer un commentaire