使用noncopyable成员聚合类的初始化

时间:2015-12-19 07:56:30

标签: c++ c++11 aggregate-initialization

假设我有一些带有删除的复制构造函数的类:

struct NoCopy
{
    NoCopy(int) {}
    NoCopy(const NoCopy &) = delete;
};

我在另一个类中使用这个类:

struct Aggregate
{
    NoCopy nc;
};

但是当我尝试使用聚合初始化时

int main()
{
    Aggregate a{3};
}

编译器输出以下错误:

error: use of deleted function ‘NoCopy::NoCopy(const NoCopy&)’

为什么聚合初始化需要类成员的副本构造函数?聚合初始化是否使用复制构造函数初始化所有成员?

1 个答案:

答案 0 :(得分:7)

您想要的正确语法是:

Aggregate aAndroidAsync;

这为NoCopy成员提供了初始化程序。如果没有额外的{},编译器需要执行从intNoCopy的转换(很高兴通过非显式构造函数执行),然后使用它来构造{{1} }。这通常会作为移动构造发生,但通过删除复制文件,您也有效地删除了移动构造函数。

考虑它的一种更简单的方法可能是想象nc有一个值构造函数采用两个参数而不是一个:

NoCopy

现在如果你写了

struct NoCopy {
    NoCopy(int, int);
};

表示Aggregate a{1, 2}; 用于初始化1,而nc用于初始化其他内容(编译时错误)。您必须为此添加额外的2才有意义

{}

第三种方法是查看函数调用:

Aggregate a{{1, 2}};

struct NoCopy { NoCopy(int) {} NoCopy(const NoCopy &) = delete; }; void fun(NoCopy) { } int main() { fun(1); // wrong fun({1}); // right } 版本中,使用// wrong构造函数在调用点构建临时NoCopy对象。然后,该临时值按值传递到NoCopy(int),但由于fun不可复制,因此失败。

NoCopy版本中,您要为要构造的参数提供初始化列表。没有制作副本。

相关问题