Можно ли проверить, что тип является экземпляром определенного шаблона?
У меня есть шаблон класса, в котором один из параметров шаблона должен быть экземпляром определенного шаблона или какого-либо другого типа. Например, рассмотрим это простое определение списка типов:
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? Можно ли написать один?