C++ 属性: no_unique_address (C++20 起)
来自 cppreference.cn
允许此数据成员与其类的其他非静态数据成员或基类子对象重叠。
目录 |
[编辑] 语法
[[no_unique_address]]
|
|||||||||
[编辑] 解释
应用于非位域的非静态数据成员声明中声明的名称。
使此成员子对象可能重叠,即允许此成员与其类的其他非静态数据成员或基类子对象重叠。这意味着如果该成员具有空类类型(例如无状态分配器),编译器可以对其进行优化以不占用任何空间,就像它是一个空基类一样。如果该成员不为空,则其任何尾部填充也可以重复使用以存储其他数据成员。
[编辑] 注意
即使在 C++20 模式下,MSVC 也忽略 [[no_unique_address]];而是提供 [[msvc::no_unique_address]]。
[编辑] 示例
运行此代码
#include <iostream> struct Empty {}; // empty class struct X { int i; Empty e; }; struct Y { int i; [[no_unique_address]] Empty e; }; struct Z { char c; [[no_unique_address]] Empty e1, e2; }; struct W { char c[2]; [[no_unique_address]] Empty e1, e2; }; int main() { // the size of any object of empty class type is at least 1 static_assert(sizeof(Empty) >= 1); // at least one more byte is needed to give e a unique address static_assert(sizeof(X) >= sizeof(int) + 1); // empty member optimized out std::cout << "sizeof(Y) == sizeof(int) is " << std::boolalpha << (sizeof(Y) == sizeof(int)) << '\n'; // e1 and e2 cannot share the same address because they have the // same type, even though they are marked with [[no_unique_address]]. // However, either may share address with c. static_assert(sizeof(Z) >= 2); // e1 and e2 cannot have the same address, but one of them can share with // c[0] and the other with c[1] std::cout << "sizeof(W) == 2 is " << (sizeof(W) == 2) << '\n'; }
可能的输出
sizeof(Y) == sizeof(int) is true sizeof(W) == 2 is true
[编辑] 参考
- C++23 标准 (ISO/IEC 14882:2024)
- 9.12.11 无唯一地址属性 [dcl.attr.nouniqueaddr]
- C++20 标准 (ISO/IEC 14882:2020)
- 9.12.10 无唯一地址属性 [dcl.attr.nouniqueaddr]