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++ プログラミング能力を向上させることができます。