C++20中能否创建不可拷贝的聚合结构体?
让C++20聚合类型不可拷贝的两种方法
在C++20标准下,确实无法通过直接声明删除拷贝构造函数的方式让聚合类型不可拷贝(因为用户声明的构造函数会让类型失去聚合属性),但有两种合法的方式实现需求:
方法一:继承一个不可拷贝的基类
定义一个仅删除拷贝构造和拷贝赋值的基类,让目标结构体公有继承该基类(无需使用using声明继承构造函数)。由于基类的拷贝操作被删除,目标结构体的默认拷贝构造/赋值会被编译器自动删除,同时结构体仍满足聚合类型的条件:
struct NonCopyableBase { // 删除拷贝构造和赋值,这属于用户声明的构造函数,但仅影响基类本身 NonCopyableBase(const NonCopyableBase&) = delete; NonCopyableBase& operator=(const NonCopyableBase&) = delete; }; // 这是一个聚合类型,且不可拷贝 struct MyAggregate : NonCopyableBase { int value; double data; };
验证:
MyAggregate没有用户声明的构造函数,也未通过using继承基类的构造函数,符合聚合类型的判定规则- 尝试拷贝
MyAggregate对象(如MyAggregate a; MyAggregate b = a;)会触发编译错误,因为默认拷贝构造被删除
方法二:包含一个不可拷贝的成员变量
在结构体中加入一个本身不可拷贝的成员(比如std::unique_ptr、std::future这类禁用拷贝的标准库类型),编译器会自动删除结构体的默认拷贝构造和赋值操作,同时结构体保持聚合属性:
#include <memory> // 这是一个聚合类型,且不可拷贝 struct MyAggregate { std::unique_ptr<int> ptr; // 不可拷贝的成员 int value; };
验证:
MyAggregate无用户声明的构造函数,满足聚合类型要求- 执行拷贝操作时,编译器会因
std::unique_ptr的拷贝限制报错,实现不可拷贝的效果
注意事项:
- 两种方法均无需声明任何用户构造函数,严格遵循聚合类型的规则
- 若需要支持移动操作,两种方式都能自动生成默认移动构造/赋值(只要基类或成员支持移动)
内容的提问来源于stack exchange,提问作者greg_p
相关产品推荐
相关产品推荐

