コンテンツにスキップ

C++/標準ライブラリ/type traits

出典: フリー教科書『ウィキブックス(Wikibooks)』

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)
Tvoid 型かどうかを確認します。
is_null_pointer<T> (C++14)
Tstd::nullptr_t 型かどうかを確認します。
is_integral<T> (C++11)
T が整数型 (例:intchar) かどうかを確認します。
is_floating_point<T> (C++11)
T が浮動小数点型 (例:floatdouble) かどうかを確認します。
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++ プログラミング能力を向上させることができます。