C++ 属性: no_unique_address (C++20 以降)
From cppreference.com
< cpp | language | attributes
このデータメンバが、そのクラスの他の非静的データメンバまたは基底クラスのサブオブジェクトと重複することを許可します。
目次 |
[編集] 構文
[[no_unique_address]]
|
|||||||||
[編集] 説明
ビットフィールドではない非静的データメンバの宣言で宣言されている名前に適用されます。
このメンバサブオブジェクトを潜在的に重複可能 (potentially-overlapping) にします。つまり、このメンバがそのクラスの他の非静的データメンバまたは基底クラスのサブオブジェクトと重複することを許可します。これは、メンバが空のクラス型 (例: ステートレスアロケータ) である場合、コンパイラが空の基底クラス (empty base) であるかのように、空間を占有しないように最適化できることを意味します。メンバが空でない場合、その中の末尾パディングも他のデータメンバを格納するために再利用される可能性があります。
[編集] 備考
MSVC では C++20 モードでも [[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 No unique address attribute [dcl.attr.nouniqueaddr]
- C++20 standard (ISO/IEC 14882:2020)
- 9.12.10 No unique address attribute [dcl.attr.nouniqueaddr]