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

8
以下代码片段导致了复制构造函数被调用,而我原本期望的是移动构造函数被调用:
#include <cstdio>

struct Foo
{
    Foo() { puts("Foo gets built!"); }
    Foo(const Foo& foo) { puts("Foo gets copied!"); }
    Foo(Foo&& foo) { puts("Foo gets moved!"); }
};

struct Bar { Foo foo; };
Bar Meow() { Bar bar; return bar; }
int main() { Bar bar(Meow()); }

在VS11 Beta中,调试模式下,这将打印:
Foo gets built!
Foo gets copied!
Foo gets copied!

我查看了标准,Bar似乎满足所有要求,可以自动生成默认的移动构造函数,但是除非有其他原因导致对象无法移动,否则似乎不会自动生成。我在这里看到了很多与移动和复制构造函数相关的问题,但我认为没有人遇到过这个特定的问题。
对于这里发生的情况有什么指示吗?这是标准行为吗?

return std::move(bar); 会改变什么吗?顺便说一下,gcc 4.7.0 调用移动构造函数(关闭复制省略)。 - Jesse Good
顺便提一下,gcc 4.6.1不会调用复制构造函数或移动构造函数。 - Michael Burr
g++ 4.5.3只创建对象:“Foo gets built!”(复制省略),而禁用复制省略时会复制两次对象。只有在有rvalue的情况下才会调用移动构造函数,我不确定Meow()是否符合条件。 - Misguided
1
如果我在Bar中明确声明了一个移动构造函数,它将被调用,因此这确实是默认移动构造函数生成的问题。 - Trillian
1个回答

8

不幸的是,VS11没有提供默认的移动构造函数。请参见“备注”部分的移动语义 - 引用以下内容:

与默认复制构造函数不同,编译器不会提供默认的移动构造函数。


好的,谢谢你的发现!这是否符合标准呢?如果不是的话,我想我会在Microsoft Connect上报告一个错误,尽管他们肯定已经知道了。 - Trillian
微软还没有完成实现所有新的C++11功能。更多信息请参见http://msdn.microsoft.com/en-us/library/hh409293%28v=vs.110%29.aspx和http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx。 - Fraser
该死,我们甚至在最终的VS11版本中都没有得到默认移动构造函数的生成 :/ - Trillian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接