C++ 属性: no_unique_address (自 C++20 起)
来自 cppreference.com
允许此数据成员与类的其他非静态数据成员或基类子对象重叠。
内容 |
[编辑] 语法
[[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 无唯一地址属性 [dcl.attr.nouniqueaddr]
- C++20 标准 (ISO/IEC 14882:2020)
- 9.12.10 无唯一地址属性 [dcl.attr.nouniqueaddr]