我怎样才能 "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
而且,嗯,它有,但也没有,因为模板实例化是不同的。
我怎样才能达到这种效果并真正让我的代码编译?
备注:
- 别管我是如何定义
constant
、constant_by_ratio
和 curry_right_hand_side
- 它们已经过测试并且可以工作。
- 如果我将第二个
is_non_negative
替换为 foo
,那么它可以编译并可用 - 但标识符不同。
- 这里两个定义的动机是不可能使用浮点值作为模板参数,但请不要关注示例的那个方面。
也许你可以这样做:
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>>> { };
我想以一种方式为整数 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
而且,嗯,它有,但也没有,因为模板实例化是不同的。
我怎样才能达到这种效果并真正让我的代码编译?
备注:
- 别管我是如何定义
constant
、constant_by_ratio
和curry_right_hand_side
- 它们已经过测试并且可以工作。 - 如果我将第二个
is_non_negative
替换为foo
,那么它可以编译并可用 - 但标识符不同。 - 这里两个定义的动机是不可能使用浮点值作为模板参数,但请不要关注示例的那个方面。
也许你可以这样做:
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>>> { };