这个问题在这里已经有一个答案:>
Doing a static_assert that a template type is another template2
是否可以检查一个类型是特定模板的实例化?
是否可以检查一个类型是特定模板的实例化?
我有一个类模板,其中一个模板参数必须是特定模板的实例化或其他类型.例如,考虑一个类型列表的简单定义:
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模板参数提供的类型始终是类型列表的实例化或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; };
标准库或Boost中是否有这样的特质(is_instantiation_of)?是可以写一个吗?
解决方法
我想出了以下解决方案,使用C 11变体模板和简单的部分专业化:
#include <type_traits> template < template <typename...> class Template,typename T > struct is_instantiation_of : std::false_type {}; template < template <typename...> class Template,typename... Args > struct is_instantiation_of< Template,Template<Args...> > : std::true_type {};