我正在对 move 语义进行一些测试,我尝试了这个:
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
我收到以下错误:
error C3086: cannot find 'std::initializer_list': you need to #include <initializer_list>
我不明白,因为初始化列表功能已添加到 VC11 和 CTP2012 nov。 这是因为我们必须等待 stdlib 的更新吗?
我认为代码是正确的,因为我从 Scott meyers 的幻灯片中复制了它:Move Semantics, Rvalue References, Perfect Forwarding .
感谢您的帮助。 供您引用,出现虚假拷贝是因为我没有通过拷贝在我的 CTOR 中添加“const”。 最好的
最佳答案
大括号 auto
将永远以 std::initializer_list<T>
结尾类型。所以基本上这里发生了什么你尝试创建一个 std::initializer_list<A>
这里是 x
而不是 A
你在这里的意图可能是什么。但是,您的代码应该可以正常编译,而这可能是 VS 最新 CTP 编译器中的错误。
制作x
属于 A
你有两个选择:
不要使用
auto
这里:A x{ create() };
不要在这里使用统一初始化:
auto x(create());
除此之外,我在您的代码中看到了另外 2 个问题。首先正确的复制构造函数的签名应该是这样的:
A(const A &) {printf("A CTOR by copy\n");}
此外,不鼓励从函数返回 RValue 引用。相反,你应该像这样按值返回:
A create(){
A v;
return v; // std::move not needed here because C++11 compiler will put it for you here
}
或者只是:
A create(){
return A();
}
编辑:
哦,为了政治正确 A(A&&)
不是“普遍引用的 CTOR”。它是“通过 move 的 CTOR”或“通过右值引用的 CTOR”,具体取决于您要操作的抽象级别。通用引用总是关于模板和特定类型的类型推导。
另请阅读我在不同评论中附上的 Scott Meyers 的文章 http://scottmeyers.blogspot.com/2012/10/copying-constructors-in-c11.html您在笔记中提到的同一位 C++ 大师准确地解释了您面临的问题。希望对您有所帮助。
关于c++ - 为什么 auto v {create()};不编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13266221/