c++ - 为什么 auto v {create()};不编译?

标签 c++ visual-c++ c++11 visual-studio-2012 move

我正在对 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你有两个选择:

  1. 不要使用 auto这里:

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

    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/

相关文章:

c++ - MFC 无法从 DLL 加载 Dlg

C++ Pi近似程序

c++ - 没有默认构造函数和已删除复制构造函数初始化的对象的类成员数组

c++ - 双右尖括号 (>>) 在特定情况下会产生语法错误

c++ - Eclipse helios(Windows 7 64 位)中 Unresolved inclusion : <stdio. h>

c++ - 通过 const 引用传递模板

c++ - std::put_time() 的问题

c++ - 对于(自动 e : xxx) conflict with constructor

具有复杂结构的 C++ 初始化列表

c++ - 顶点着色器中的统一采样器2D