C++ 属性: no_unique_address (自 C++20 起)
来自 cppreference.cn
< cpp | language | attributes
允许此数据成员与其类的其他非静态数据成员或基类子对象重叠。
目录 |
[编辑] 语法
[[no_unique_address]]
|
|||||||||
[编辑] 解释
应用于非静态数据成员声明中声明的名称,该成员不是位字段。
使此成员子对象成为潜在重叠,即允许此成员与其类的其他非静态数据成员或基类子对象重叠。这意味着如果成员具有空类类型(例如,无状态分配器),编译器可以优化它以不占用空间,就像它是空基类优化一样。如果成员不为空,则其中的任何尾部填充也可能被重用以存储其他数据成员。
[编辑] 注意
[[no_unique_address]] 在 MSVC 中即使在 C++20 模式下也会被忽略;相反,提供了 [[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 No unique address attribute [dcl.attr.nouniqueaddr]
- C++20 标准 (ISO/IEC 14882:2020)
- 9.12.10 No unique address attribute [dcl.attr.nouniqueaddr]