具有不可复制成员的类的聚合初始化
Aggregate initialization of class with noncopyable member
假设我有一些删除复制构造函数的类:
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&)’
为什么聚合初始化需要类成员的复制构造函数?聚合初始化是否使用复制构造函数初始化所有成员?
您想要的正确语法是:
Aggregate a{{3}};
这为 NoCopy
成员提供了一个初始值设定项。如果没有额外的{}
编译器需要执行从 int
到 NoCopy
的转换(它很高兴通过非显式构造函数执行此操作(,然后使用它来构造nc
。 这通常作为移动构造发生,但通过删除复制 ctor,您也有效地删除了移动构造函数。
一种更简单的思考方法可能是想象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(int)
构造函数在调用站点构造临时NoCopy
对象。然后临时通过值传递到fun
,但由于NoCopy
不可复制,所以失败。
在// right
版本中,您将为要用来构造的参数提供初始值设定项列表。不制作副本。
相关文章:
- 为什么在C++中首先初始化成员类
- 是否可以防止省略聚合初始化成员?
- 正在复制具有未初始化成员的结构
- 使用大括号或括号初始化成员变量
- C++结构:强制初始化成员?
- C++中未初始化成员布尔变量的默认值是多少?
- 使用默认值初始化成员引用
- 在构造函数中初始化成员时,是否应该在成员上使用 std::move?
- C++使用 { } 初始化成员变量
- 如何根据构造函数参数使用超类类型初始化成员变量?
- OpenGL C++:VBO 的结构包装器不会初始化成员
- 有没有办法在Brace中初始化成员
- 从现有 istream 或类本身创建的 istream 初始化成员 istream
- 从其后声明的另一个成员数据初始化成员数据是否为未定义行为
- 通常应用方法,使用带有构造函数委托的 SFINAE 通过类模板的构造函数初始化成员
- 如何在嵌套类中初始化成员?C
- 是否可以在构造函数主体中初始化成员变量,而不是初始值设定项列表
- 编译器错误,因为构造函数必须显式初始化成员
- 如何使用成员函数初始化成员函数指针
- C 如何使用隐藏的默认构造函数初始化成员