yohhoyの日記

技術的メモをしていきたい日記

クラステンプレート特殊化型判定

プログラミング言語C++において、与えられた型があるクラステンプレートの特殊化(specialization)か否かを判定する方法。

下記コードは複素数std::complexの特殊化か否かを判定するメタ関数およびコンセプト実装例。

// C++11/14/17: is_complexメタ関数
#include <complex>
#include <type_traits>

template <typename T>
struct is_complex : std::false_type {};
template <typename T>
struct is_complex<std::complex<T>> : std::true_type {};

static_assert( is_complex<std::complex<float>>::value );
static_assert( !is_complex<double>::value );
// C++20: is_complexコンセプト
#include <concepts>
#include <complex>

template <typename T>
concept is_complex = requires (T t) {
  { std::complex{std::move(t)} } -> std::same_as<T>;
  // ムーブのみ可能な型を考慮してrvalueへキャスト
  // コピー可能な型では単にt(lvalue)記述でもよい
};

static_assert( is_complex<std::complex<float>> );
static_assert( !is_complex<double> );

メタ関数バージョンは非型テンプレートパラメータ(non-type template parameter)を含むクラステンプレート(例:std::array, std::span)には利用できない。コンセプトバージョンはコピー/ムーブ不可のクラステンプレート(例:std::atomic, std::counting_semaphore)には利用できない。

関連URL

*1:提案 P2098R1 は2020年5月会合で棄却済み。https://github.com/cplusplus/papers/issues/812 参照。