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