名前空間
変種
操作

属性: no_unique_address (C++20以上)

提供: cppreference.com
< cpp‎ | language‎ | attributes
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定(C++20未満)
noexcept 指定子(C++11)
例外
名前空間
指定子
decltype(C++11)
auto(C++11)
alignas(C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr(C++11)
ユーザ定義(C++11)
ユーティリティ
属性(C++11)
typedef 宣言
型エイリアス宣言(C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 
属性
(C++14)
(C++17)
(C++20)(C++20)
no_unique_address
(C++20)
 

そのデータメンバがそのクラスの他のすべての非静的データメンバと異なるアドレスを持つ必要がないことを示します。

[編集]構文

[[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 outstd::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
close