我怎样才能 "ostensibly-but-not-really" 打破 enable_if 和 SFINAE 的单一定义规则?

How can I "ostensibly-but-not-really" break the one-definition-rule with enable_if and SFINAE?

我想以一种方式为整数 T 定义 template <typename T> struct is_non_negative,为浮点数 T 定义另一种方式。这是我所做的:

template<typename T>
struct is_non_negative: public curry_right_hand_side<greater_equal<
    typename std::enable_if<std::is_integral<T>::value, T>::type>, constant<T, 0>> { };

template<typename T>
struct is_non_negative: public curry_right_hand_side<greater_equal<
    typename std::enable_if<std::is_floating_point<T>::value, T>::type>, constant_by_ratio<T, std::ratio<0,1>>> { };

这会触发编译器错误(GCC 4.9.3,-std=c++11):

error: class template "cuda::is_non_negative" has already been defined

而且,嗯,它有,但也没有,因为模板实例化是不同的。

我怎样才能达到这种效果并真正让我的代码编译?

备注:

也许你可以这样做:

template<class T, class = void>
struct is_non_negative;

template<typename T>
struct is_non_negative<T, typename std::enable_if<std::is_integral<T>::value>::type>: public curry_right_hand_side<greater_equal<T>, constant<T, 0>> { };

template<typename T>
struct is_non_negative<T, typename std::enable_if<std::is_floating_point<T>::value>::type>: public curry_right_hand_side<greater_equal<T>, constant_by_ratio<T, std::ratio<0,1>>> { };