C++/標準ライブラリ/type traits
C++教科書/標準ライブラリ編/<type_traits>の章
[編集]はじめに
[編集]<type_traits>
ヘッダーは、C++11 で導入された C++ 標準ライブラリのメタプログラミング機能の一部です。 さまざまなデータ型を扱う汎用的なコンパイル時評価コードを書くために使用できるクラスとヘルパー関数のセットを提供します。 これらのトレイトを使用して、コンパイル時に型のプロパティを分析し、より堅牢で柔軟なコードを作成できます。
ヘルパークラス
[編集]integral_constant<T, v>
(C++11)- このクラス テンプレートは、特定の型
T
のコンパイル時定数オブジェクトを指定された値v
で作成するためのヘルパーとして機能します。 bool_constant<B>
(C++11)- これは
bool
型のintegral_constant
の特殊化です。 コンパイル時に定数ブール値を作成します。 - 例:
using true_type = std::bool_constant<true>; using false_type = std::bool_constant<false>;
基本的な型カテゴリ
[編集]これらのトレイトは、型が特定の基本カテゴリに属しているかどうかを確認します。 各トレイトは型テンプレートであり、型をパラメータとして受け取り、条件が満たされる場合は std::integral_constant<bool, true>
を返し、そうでない場合は std::integral_constant<bool, false>
を返します。 さらに、これらのトレイトのほとんどには、直接 bool
値を返す対応する constexpr バージョンがあります。
is_void<T>
(C++11)T
がvoid
型かどうかを確認します。is_null_pointer<T>
(C++14)T
がstd::nullptr_t
型かどうかを確認します。is_integral<T>
(C++11)T
が整数型 (例:int
、char
) かどうかを確認します。is_floating_point<T>
(C++11)T
が浮動小数点型 (例:float
、double
) かどうかを確認します。is_array<T>
(C++11)T
が配列型かどうかを確認します。is_enum<T>
(C++11)T
が列挙型かどうかを確認します。is_union<T>
(C++11)T
が共用体型かどうかを確認します。is_class<T>
(C++11)T
が非共用体のクラス型かどうかを確認します。is_function<T>
(C++11)T
が関数型かどうかを確認します。is_pointer<T>
(C++11)T
がポインタ型かどうかを確認します。is_lvalue_reference<T>
(C++11)T
が左辺値参照型かどうかを確認します。is_rvalue_reference<T>
(C++11)T
が右辺値参照型かどうかを確認します。is_member_object_pointer<T>
(C++11)T
が非静的メンバ オブジェクトへのポインタかどうかを確認します。is_member_function_pointer<T>
(C++11)T
が非静的メンバ関数へのポインタかどうかを確認します。
複合型カテゴリ
[編集]これらのトレイトは、基本的な型を組み合わせて形成できるより広いカテゴリの型をチェックします。 基本的な型カテゴリと同様に、これらは std::integral_constant
を返し、constexpr 対応するものがあります。
is_reference
- 型が左辺値または右辺値参照型かどうかを確認します。
is_fundamental
- 型が基本型 (void、整数型、浮動小数点型、および bool を含む) かどうかを確認します。
is_arithmetic
- 型が算術型 (整数型または浮動小数点型) かどうかを確認します。
is_scalar
- 型がスカラ型 (整数型、浮動小数点型、または bool) かどうかを確認します。
is_compound
- 型が複合型 (配列型、共用体型、または構造体型) かどうかを確認します。
is_pointer
- 型がポインタ型かどうかを確認します。
is_abstract
- 型が抽象型 (仮想関数を持つクラス) かどうかを確認します。
is_polymorphic
- 型が多態性型 (仮想関数を持つクラス) かどうかを確認します。
is_signed
- 型が符号付き型かどうかを確認します。
is_unsigned
- 型が符号なし型かどうかを確認します。
is_standard_layout
- 型が標準レイアウトを持っているかどうかを確認します。
is_trivial_copyable
- 型が自明にコピー可能かどうかを確認します。
is_trivial_assignable
- 型が自明に代入可能かどうかを確認します。
is_destructible
- 型が破棄可能かどうかを確認します。
is_trivial_destructible
- 型が自明に破棄可能かどうかを確認します。
これらのトレイトを使用することで、コンパイル時に型情報を検査し、より汎用的で効率的なコードを書くことができます。
型特性の抽出
[編集]<type_traits>
ヘッダーは、型に関するさまざまな特性を抽出するためのトレイトを多数提供します。 これらのトレイトは、コンパイル時に型情報を検査し、テンプレートコードをより柔軟かつ効率的にするのに役立ちます。
以下に、いくつかの重要な型特性と説明を示します。
- 型識別
-
is_void
- 型が
void
型かどうかを確認します。 is_null_pointer
- 型が
std::nullptr_t
型かどうかを確認します。 is_integral
- 型が整数型 (例:
int
,char
) かどうかを確認します。 is_floating_point
- 型が浮動小数点型 (例:
float
,double
) かどうかを確認します。 is_array
- 型が配列型かどうかを確認します。
is_enum
- 型が列挙型かどうかを確認します。
is_union
- 型が共用体型かどうかを確認します。
is_class
- 型が非共用体のクラス型かどうかを確認します。
is_function
- 型が関数型かどうかを確認します。
is_pointer
- 型がポインタ型かどうかを確認します。
is_lvalue_reference
- 型が左辺値参照型かどうかを確認します。
is_rvalue_reference
- 型が右辺値参照型かどうかを確認します。
is_member_object_pointer
- 型が非静的メンバ オブジェクトへのポインタかどうかを確認します。
is_member_function_pointer
- 型が非静的メンバ関数へのポインタかどうかを確認します。
- 型関係
-
is_same
- 2つの型が同じかどうかを確認します。
is_convertible
- ある型が別の型に変換可能かどうかを確認します。
is_base_of
- ある型が別の型の基底型かどうかを確認します.
is_derived_from
- ある型が別の型の派生型かどうかを確認します.
- 型特性
-
alignment_of
- 型の配置要件を取得します。
rank_of
- 型のランクを取得します (配列の場合は次元数)。
extent_of
- 固定長の配列の範囲を取得します。
sizeof
- 型のサイズ (バイト単位) を取得します。
type_traits::value_type
- 型エイリアス
typename std::type_traits<T>::value_type
は、T
がポインタ型の場合はT
が指す型、そうでない場合はT
自身を定義します。 type_traits::reference_type
- 型エイリアス
typename std::type_traits<T>::reference_type
は、T
が参照型の場合はT
が指す型、そうでない場合はT
自身を定義します。 type_traits::pointer_type
- 型エイリアス
typename std::type_traits<T>::pointer_type
は、T
がポインタ型の場合はT
の要素型へのポインタ型、そうでない場合はT
自身を定義します。
- その他
-
is_adl_handler
- 型が
std::is_same
およびstd::is_convertible
のための特化テンプレートを提供しているかどうかを確認します。 has_trivial_destructor
- 型が自明のデストラクタを持っているかどうかを確認します。
is_trivial_copyable
- 型が自明にコピー可能かどうかを確認します。
is_standard_layout
- 型が標準レイアウトを持っているかどうかを確認します。
is_polymorphic
- 型が多態性を持っているかどうかを確認します。
テンプレート特化
[編集]<type_traits>
ヘッダーは、テンプレート特化に使用できるいくつかのトレイトを提供します。
例えば:
template <typename T> void f(T x) { // 型 T が整数型の場合は特別な処理を行う if constexpr (std::is_integral_v<T>) { // ... } else { // ... } }
この例では、f
テンプレートは、引数が整数型の場合にのみ特別な処理を実行します。 これは、std::is_integral_v<T>
トレイトを使用して、コンパイル時に T
が整数型かどうかを検査することによって実現されます。
コンパイル時アサーション
[編集]<type_traits>
ヘッダーは、コンパイル時アサーションを実行するために使用できる static_assert
マクロを提供します。 コンパイル時アサーションは、コンパイル時に特定の条件が満たされていることを確認するために使用されます。 条件が満たされない場合、コンパイル エラーが発生します。
template <typename T> void g(T x) { static_assert(std::is_integral_v<T>, "T must be an integral type"); // ... }
この例では、g
テンプレートは、引数が整数型であることをコンパイル時に確認します。 std::is_integral_v<T>
トレイトを使用して T
が整数型かどうかを検査し、static_assert
マクロを使用して条件が満たされない場合にコンパイル エラーを生成します。
まとめ
[編集]<type_traits>
ヘッダーは、C++ プログラマーにとって強力なツールです。 型情報をコンパイル時に検査し、より汎用的で効率的なコードを書くために使用できます。 このヘッダーを習得すると、C++ プログラミング能力を向上させることができます。