c 11 – 为什么调用复制构造函数而不是移动构造函数?

请查看以下示例代码:

   #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());
    }

我希望这段代码的输出应该是:

Default!
Move!

但我得到的是:

Default!
Copy!

我看不出为什么调用复制构造函数而不是移动构造函数的原因.如果我把关键字const放在Bar&那个结构栏的复制构造函数的声明中,我得到了正确的结果.我知道在很多情况下采用const左值引用而不仅仅是复制构造函数的左值引用更好,但我只是想知道发生这种情况的原因.

为什么在这个例子中Bar&比Bar&& amp;即使f()的返回值应该被视为prvalue?为什么关键字const解决了这个问题? const真的解决了这个问题吗?它与RVO(返回值优化)有关吗?或者,这只是一个编译器错误?

我在Visual C 2012年11月的CTP上测试了这个例子.

我在这里发现了类似的问题:

Copy constructor is being called instead of the move constructor

但我仍然无法理解为什么.

谁能帮我?

最佳答案
哇,当我用…编译时

> Debug中的Visual Studio我看到“默认!复制!”.
> Release中的Visual Studio我看到“默认!”.
>如果您将Bar(Bar& that)更改为Bar(const Bar& that),则“Default!Move!”
>令人震惊的是,如果你用Bar(Bar&& that)切换Bar(Bar& that)的顺序(以便首先定义移动ctor),那么你实际上会看到“Default!Move!”

转载注明原文:c 11 – 为什么调用复制构造函数而不是移动构造函数? - 代码日志