类属性说明符 (自 C++26 起)
指定一个类是*可替换的*(replaceable_if_eligible),*可平凡重定位的*(trivially_relocatable_if_eligible),或者一个类不能被派生(final)。
目录 |
[编辑] 语法
类属性说明符出现在类定义的开头,紧接在类名之后,并且不能出现在类声明中。
class-key attr (可选) class-head-name class-prop-specifier-seq (可选) base-clause (可选) | |||||||||
class-prop-specifier-seq | - | 一个或多个 class-prop-specifier ,但每个最多只能出现一次。 |
class-prop-specifier | - | 以下之一:final、replaceable_if_eligible 和 trivially_relocatable_if_eligible。 |
在 C++26 之前,class-prop-specifier-seq (可选) 的位置是 class-virt-specifier (可选),它只允许对 final
说明符 (自 C++11 起)使用 final。
[编辑] 解释
final、replaceable_if_eligible 和 trivially_relocatable_if_eligible 是在类头中使用时具有特殊含义的标识符。在其他上下文中,它们不是保留字,可以用于命名对象和函数。
[编辑] final 说明符
final 指定此类不能出现在其他类定义的 base-specifier-list 中(换句话说,不能被派生)。否则程序将是病态的(会生成编译时错误)。final 也可以与 union 定义一起使用,在这种情况下它没有效果(除了对 std::is_final 结果的影响)(自 C++14 起),因为 union 不能被派生。
[编辑] replaceable_if_eligible 说明符
replaceable_if_eligible 指定如果该类符合替换条件,则它是可替换的。
[编辑] trivially_relocatable_if_eligible 说明符
trivially_relocatable_if_eligible 指定如果该类符合平凡重定位条件,则它是可平凡重定位的。
[编辑] 可替换性
如果类 C
符合替换条件 且满足以下任一条件,则它是可替换的:
[编辑] 替换资格
类 C
符合替换条件,除非满足以下任一条件:
- 它有一个基类不是可替换的类
- 它有一个非静态数据成员不是可替换的类型
- 当从类型
C
的右值直接初始化类型为C
的对象时,重载决议失败或选择了一个被删除的构造函数 - 当从类型
C
的右值赋值给类型C
的左值时,重载决议失败或选择了一个被删除的赋值运算符函数 - 它有一个被删除的析构函数。
[编辑] 平凡重定位性
如果一个类符合平凡重定位条件,并且满足以下任一条件,则它是可平凡重定位的:
[编辑] 平凡重定位资格
一个类符合平凡重定位的条件,除非它具有以下任一情况:
但是,对于一个本来符合条件的,拥有一个或多个多态类子对象的union
,其是否符合平凡重定位的条件是实现定义的。
[编辑] 默认可移动性
如果满足以下所有条件,则类 C
默认可移动:
- 从类型
C
的右值直接初始化类型C
的对象的重载决议,选择了一个直接成员于C
且既非用户提供也未删除的构造函数 - 从类型
C
的右值赋值给类型C
的左值的重载决议,选择了一个直接成员于C
且既非用户提供也未删除的赋值运算符函数 -
C
有一个既非用户提供也未删除的析构函数。
[编辑] 关键词
final, replaceable_if_eligible, trivially_relocatable_if_eligible。
[编辑] 注意
- 并非所有可平凡复制的类都是可替换的或可平凡重定位的。
- 在确定平凡重定位性或可替换性时,不考虑特殊成员函数的可访问性。
- 带有 const 限定或引用类型的非静态数据成员的类可以是可平凡重定位的。
- 没有用户声明的特殊成员函数的
union
和默认可移动的类既是可替换的,也是可平凡重定位的,即使在定义时没有类属性说明符。
功能测试宏 | 值 | 标准 | 特性 |
---|---|---|---|
__cpp_trivial_relocatability |
202502L |
(C++26) | 平凡重定位性 |
[编辑] 示例
struct final; // OK; declares a class named 'final', // does not use class property specifiers. struct IF final; // Ill-formed: class property specifiers // cannot appear at function declaration. struct F final {}; // OK; specifier marks class F as non-derivable. struct D: F {}; // Ill-formed: class F cannot be derived from. // OK; specifier marks class R as 𝘳𝘦𝘱𝘭𝘢𝘤𝘦𝘢𝘣𝘭𝘦 if eligible. struct R replaceable_if_eligible {}; // OK; specifier marks class T as 𝘵𝘳𝘪𝘷𝘪𝘢𝘭𝘭𝘺 𝘳𝘦𝘭𝘰𝘤𝘢𝘵𝘢𝘣𝘭𝘦 if eligible. struct T trivially_relocatable_if_eligible {}; // OK; a class can be marked with multiple class property specifiers. struct FRT final replaceable_if_eligible trivially_relocatable_if_eligible {}; // Ill-formed: each class property specifier can appear at most once. struct FRF final replaceable_if_eligible final {}; int main() {}
[编辑] 参考
- C++26 标准 (ISO/IEC 14882:2026)
- 6.8.1 平凡重定位和可替换类型 [basic.types.general]
[编辑] 另请参阅
final 说明符 (C++11) |
声明一个方法不能被重写或一个类不能被派生 |
(C++14) |
检查类型是否为 final 类类型 (类模板) |