假设您有一个名为 Product 的类,定义如下:
class Product
{
public:
Product(const char *name, int i);
Product(Product &&rhs);
Product(const Product &rhs);
~Product();
private:
const char *m_name;
int m_i;
};
然后像这样初始化一个变量:
auto p = Product{"abc",123};
我认为标准规定编译器必须在逻辑上执行以下操作:
- 构建一个临时产品
- move-construct p(使用临时产品)
但是允许编译器对此进行优化,以便直接构造 p。
我验证了这一点(Visual Studio 2013),事实上,编译器对此进行了优化,即使我们有自己的自定义(非默认)移动构造函数。这可以。
但是,如果我明确删除复制和移动构造函数,如下所示:
class Product
{
public:
Product(const char *name, int i);
Product(Product &&rhs) = delete;
Product(const Product &rhs) = delete;
~Product();
private:
const char *m_name;
int m_i;
};
auto+brace 初始化仍然可以编译。我虽然编译器不得不阻止这种情况,因为不允许复制或移动。
奇怪的是,如果我将删除的复制和移动构造函数设为私有,如下所示:
class Product
{
public:
Product(const char *name, int i);
~Product();
private:
Product(Product &&rhs) = delete;
Product(const Product &rhs) = delete;
const char *m_name;
int m_i;
};
然后 auto+brace 初始化不再编译。
error C2248: 'Product::Product' : cannot access private member declared in class 'Product'
这是预期的行为吗?这是 Visual Studio 2013(更新 3)中的错误吗?
注意:我尝试在ideone上编译它,当复制和移动构造函数被删除(和公共)时,它确实拒绝编译初始化。所以我认为这是一个 Visual Studio 错误。