型が特定のテンプレートのインスタンス化であることを確認することは可能ですか?
テンプレート パラメーターの 1 つが特定のテンプレートのインスタンス化か、その他の型のいずれかでなければならないクラス テンプレートがあります。たとえば、次のタイプリストの簡単な定義を考えてみましょう。
struct null_type;
template <typename Head, typename Tail>
struct typelist
{
// Tail must be a typelist or null_type
typedef Head head;
typedef Tail tail;
};
Tail
ここで、テンプレート パラメーターに提供される型が常に または のインスタンス化であるtypelist
ことを確認したいと思いますnull_type
。次のように、部分的な特殊化を使用して、そのような場合にのみテンプレートを定義できます。
template <typename Head, typename Tail>
struct typelist; // default, not defined
template <typename Head, typename H, typename T>
struct typelist< Head, typelist<H,T> > // Tail = typelist, ok
{
typedef Head head;
typedef typelist<H,T> tail;
};
template <typename Head>
struct typelist< Head, null_type > // Tail = null_type, ok
{
typedef Head head;
typedef null_type tail;
};
ただし、コードを複製することになります。これは避けたいことです。理想的には、型がテンプレートのインスタンス化であるかどうかをテストし、それenable_if
を静的アサーションで、または静的アサーションで使用するための特性が必要です。
#include <boost/mpl/or.hpp>
#include <type_traits>
struct null_type;
template <typename Head, typename Tail>
struct typelist
{
static_assert(
boost::mpl::or_<
is_instantiation_of< typelist, Tail >,
std::is_same< Tail, null_type >
>::value,
"Tail must be a typelist or null_type" );
typedef Head head;
typedef Tail tail;
};
そのような特性 ( is_instantiation_of
) は、標準ライブラリまたは Boost で既に利用可能ですか? 1つ書くことは可能ですか?