有没有办法检查一个类型是否是特定模板的实例化?
我有一个类模板,其中一个模板参数必须是特定模板的实例化或其他类型。例如,考虑这个简单的类型列表定义:
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;
};
然而,我最终会重复代码,这是我想避免的。理想情况下,我需要一个trait来测试类型是否是模板的实例化,以便在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;
};
在标准库或Boost中是否已经存在这样的特性(is_instantiation_of
)?能否自己编写一个?
Template
参数是一个具有非类型参数的模板,例如template<class T, int I> struct foo{...}
(适用于 gcc 4.7),则该解决方案会出现错误。 - Mike Kinghanstd::array
和所有这类模板中工作 - 请参见先前的评论 - PiotrNycz