SFINAE专门针对CRTP结构的特征

yva*_*ros 2 c++ crtp sfinae template-specialization c++11

我试图专门化一些特征(例如在cppunit中的std :: is_arithmetic或assertion_traits)用于模板类(CRTP),它可以保存模板参数类型的值(类似于BOOST_STRONG_TYPEDEF)

我尝试使用SFINAE限制我的专业化

示例代码适用于gcc6和upper,但不能使用Visual c + +编译(2015或2017)

error C2753: 'is_ar<T>': partial specialization cannot match argument list for primary template
Run Code Online (Sandbox Code Playgroud)

或clang6

error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list
Run Code Online (Sandbox Code Playgroud)

示例代码:

template<class T, typename B>
struct Base
{
    using typed_type = T ;
    using  base_type = B ;
    base_type x;
}; 

template <typename T>
struct MyType
{
    using base_type = T;
    base_type x;
};

struct CRTPInt : Base<CRTPInt, int> { };

 template <typename T>
struct is_ar 
{
    static const bool value = false;
};

template <>
struct is_ar<int>
{
    static const bool value = true;
};

template <class T, typename...>
using typer = T;


template <typename T>
struct is_ar<typer<T, typename T::base_type, typename T::typed_type>> : is_ar<typename T::base_type>
{
    static const bool value = true;
};


static_assert(is_arithmetic<CRTPInt>::value, "failed");
static_assert(is_arithmetic<CRTPInt::base_type>::value, "failed");
Run Code Online (Sandbox Code Playgroud)

我做错了什么 ?

这是有效的c ++ 11吗?如何使用Visual C++编译器?

假设我可以修改特征的初始定义,来自max66的答案很好.但实际上我想专门为宏创建的类的框架特征(例如cppunit :: assertion_traits)

#define MY_TYPEDEF(type , base) struct type: Base<type , base> { };
Run Code Online (Sandbox Code Playgroud)

这个宏声明的类不是模板类,所以我找不到专门为这种方式生成的所有类的方法.

唯一的共同点是定义了类型名base_typetyped_type.

任何的想法 ?

Que*_*tin 6

[meta.type.synop:1]
除非另有说明,否则为本子条款中定义的任何模板添加特化的程序的行为是未定义的.

该小节包括std::is_arithmetic,所以不幸的是你根本不允许这种专业化.