0Pricing
C++ Academy · レッスン

カスタムtraitsの作成

独自の型traitsを構築します

「カスタムtraitsの作成」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

独自のトレイトを作成する

標準ライブラリに必要な問いに対応する機能がない場合は、カスタムトレイトを作成できます。トレイトとは、::valueまたは::typeを公開するテンプレートです。

プライマリテンプレートと特殊化

標準的なパターンは、falseをデフォルトとするプライマリテンプレートと、対象の型に一致してtrueを設定する特殊化を組み合わせることです。

#include <iostream>
#include <type_traits>

template <typename T>
struct is_ptr : std::false_type {};

template <typename T>
struct is_ptr<T*> : std::true_type {};

int main() {
    std::cout << is_ptr<int>::value << "\n";
    std::cout << is_ptr<int*>::value << "\n";
    return 0;
}

integral_constantからの継承

std::true_typeまたはstd::false_typeを継承すると、トレイトは自動的にvalueメンバーを持ち、標準トレイトと同じように動作します。

コンテナの検出

ネストされたメンバーの有無を調べることで、型がコンテナらしいかどうかを検出できます。ここでは、ヘルパーを使ってvalue_type typedefの存在に基づく特殊化を行います。

#include <iostream>
#include <vector>
#include <type_traits>

template <typename T, typename = void>
struct has_value_type : std::false_type {};

template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};

int main() {
    std::cout << has_value_type<std::vector<int>>::value << "\n";
    std::cout << has_value_type<int>::value << "\n";
    return 0;
}

std::void_tの解説

std::void_t<...>は、有効な型のリストをすべてvoidに変換します。内部の型のいずれかが不正な形式の場合、その特殊化はSFINAEによって除外されるため、プライマリのfalse_typeが選ばれます。

メンバー関数の検出

void_tの中で式を評価することで、型に呼び出し可能なsize()があるかどうかを検出できます。

#include <iostream>
#include <string>
#include <type_traits>

template <typename T, typename = void>
struct has_size : std::false_type {};

template <typename T>
struct has_size<T, std::void_t<decltype(std::declval<T>().size())>> : std::true_type {};

int main() {
    std::cout << has_size<std::string>::value << "\n";
    std::cout << has_size<int>::value << "\n";
    return 0;
}

declval

std::declval<T>()は、未評価コンテキストで型Tの仮の値を生成します。これにより、オブジェクトを構築せずにdecltype式を記述できます。

変換トレイト

カスタムトレイトは型を生成することもできます。これはポインターの層を1つ取り除くトレイトです。

#include <iostream>
#include <type_traits>

template <typename T>
struct remove_one_pointer { using type = T; };

template <typename T>
struct remove_one_pointer<T*> { using type = T; };

int main() {
    using R = remove_one_pointer<int*>::type;
    std::cout << std::is_same_v<R, int> << "\n";
    return 0;
}

_vと_tのヘルパーを提供する

変数テンプレートとエイリアステンプレートを追加して、標準ライブラリと同じスタイルにします。

#include <iostream>
#include <type_traits>

template <typename T>
struct is_char : std::false_type {};
template <>
struct is_char<char> : std::true_type {};

template <typename T>
inline constexpr bool is_char_v = is_char<T>::value;

int main() {
    std::cout << is_char_v<char> << "\n";
    std::cout << is_char_v<int> << "\n";
    return 0;
}

検出イディオム

void_tの手法は検出イディオムへと一般化されます。実験的なstd::is_detectedがこれを形式化しています。C++20のコンセプトを使うと、この処理の多くがより明瞭になります。

トレイトをテストする

static_assertでカスタムトレイトを検証すると、回帰が発生したときに直ちにビルドを失敗させることができます。

#include <type_traits>

template <typename T>
struct is_void_like : std::false_type {};
template <>
struct is_void_like<void> : std::true_type {};

static_assert(is_void_like<void>::value);
static_assert(!is_void_like<int>::value);

int main() { return 0; }

確認問題

std::void_tの役割を思い出してください。

まとめ

カスタムトレイトの作成方法を学びました。

  • プライマリテンプレートはfalseをデフォルトとし、特殊化でtrueを設定します
  • true_type/false_typeを継承します
  • void_tとdeclvalが検出イディオムを支えます
  • _v/_tヘルパーを追加し、static_assertでテストします

よくある質問

「カスタムtraitsの作成」レッスンは無料ですか?

はい。「カスタムtraitsの作成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「カスタムtraitsの作成」で何を学びますか?

独自の型traitsを構築します ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「カスタムtraitsの作成」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型の問い合わせ
  2. 型の変換
  3. 条件分岐
  4. カスタムtraitsの作成
← C++ Academyに戻る