为什么要自动v {create()}; 不编译?

dza*_*ada 1 c++ move visual-c++ c++11 visual-studio-2012

我正在做一些移动语义的测试,我试过这个:

class A{
public:
    A(){printf("A CTOR\n");}
    A(A&) {printf("A CTOR by copy\n");}
    A(A&&){printf("A CTOR by universal reverence\n");}
};

A&& create(){
    A v;
    return std::move(v);
}

auto x{ create() };//this does not compile

float d[]{1.2,1.3,5,6};//this does compile
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error C3086: cannot find 'std::initializer_list': you need to #include <initializer_list>
Run Code Online (Sandbox Code Playgroud)

我不明白,初始化列表功能已添加到VC11与CTP2012 nov.这是因为我们必须等待stdlib的更新吗?

我认为代码是正确的,因为我从Scott meyers的幻灯片中复制它:Move Semantics,Rvalue References,Perfect Forwarding.

谢谢您的帮助. 为了您的信息,发生了虚假副本,因为我没有在我的CTOR中添加"const"副本. 最好

Mat*_*usz 6

大括号auto总会以std::initializer_list<T>类型结束.所以基本上在这里你会尝试创建一个std::initializer_list<A>for x而不是A你的意图.但是,您的代码应该编译正常,这可能是VS最新CTP编译器中的错误.

为了使xBE的A你有2种选择:

  1. 不要auto在这里使用:

    A x{ create() };
    
    Run Code Online (Sandbox Code Playgroud)
  2. 不要在这里使用统一初始化:

    auto x(create());
    
    Run Code Online (Sandbox Code Playgroud)

除此之外,我在您的代码中看到了其他2个问题.首先,正确的拷贝构造函数的签名应如下所示:

A(const A &) {printf("A CTOR by copy\n");}
Run Code Online (Sandbox Code Playgroud)

此外,不鼓励从函数返回RValue引用.相反,你应该像这样返回值:

A create(){
  A v;
  return v;   // std::move not needed here because C++11 compiler will put it for you here
}
Run Code Online (Sandbox Code Playgroud)

要不就:

A create(){
  return A();
}
Run Code Online (Sandbox Code Playgroud)

编辑:

哦,只是在政治上A(A&&) 正确的不是 "通用参考的CTOR".根据您想要操作的抽象级别,它是"移动的CTOR"或"移动参考的CTOR".通用引用始终是关于模板和特定类型类型的推导.

另请阅读Scott Meyers的一篇文章,我在另一篇评论http://scottmeyers.blogspot.com/2012/10/copying-constructors-in-c11.html中附上了你在笔记中提到的同一个C++专家你遇到的问题.希望有所帮助.