C++ 属性: no_unique_address (C++20 起)

来自cppreference.com
< cpp‎ | language‎ | attributes

指示此数据成员不需要具有不同于其类的所有其他非静态数据成员的地址。

语法

[[no_unique_address]]

解释

应用到非位域非静态数据成员的声明中所声明的名字。

指示此数据成员不需要具有不同于其类的所有其他非静态数据成员的地址。这表示若该成员拥有空类型(例如无状态分配器),则编译器可将它优化为不占空间,正如同假如它是空基类一样。若该成员非空,则其中的任何尾随填充空间亦可复用于存储其他数据成员。

示例

#include <iostream>
 
struct Empty {}; // 空类
 
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()
{
    // 任何空类类型对象的大小至少为 1
    static_assert(sizeof(Empty) >= 1);
 
    // 至少需要多一个字节以给 e 唯一地址
    static_assert(sizeof(X) >= sizeof(int) + 1);
 
    // 优化掉空成员
    std::cout << "sizeof(Y) == sizeof(int) is " << std::boolalpha 
              << (sizeof(Y) == sizeof(int)) << '\n';
 
    // e1 与 e2 不能共享同一地址,因为它们拥有相同类型,尽管它们标记有 [[no_unique_address]]。
    // 然而,其中一者可以与 c 共享地址。
    static_assert(sizeof(Z) >= 2);
 
    // e1 与 e2 不能拥有同一地址,但它们之一能与 c[0] 共享,而另一者与 c[1] 共享
    std::cout << "sizeof(W) == 2 is " << (sizeof(W) == 2) << '\n';
}

可能的输出:

sizeof(Y) == sizeof(int) is true
sizeof(W) == 2 is true