当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《使用noncopyable成员聚合类的初始化》经验,为你挑选了1个好方法。

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

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> Ryan Haining..:

您想要的正确语法是:

Aggregate a{{3}};

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

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

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

现在如果你写了

Aggregate a{1, 2};

这表明它1用于初始化nc2用于初始化其他东西(编译时错误).你必须添加额外的东西才有{}意义

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不可复制,因此失败.

在该// right版本中,您将为要构造的参数提供初始化列表.没有制作副本.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有