c ++模板运算符重载std :: enable_if

时间:2016-02-15 11:52:01

标签: c++ templates compiler-errors

我在编译此模板时遇到问题。我只想创建一个运算符,其功能取决于数据类型(int或float)。 我不是专家,所以我将不胜感激。

template <class T> struct eq {
  typename std::enable_if<std::is_floating_point<T>::value, T>::type
  operator() (const T& x, const T& y) const {
    T* paux;
    if(sizeof(T) == 4){ //float
      uint32_t val = 0;
      if(x == y){
    val = ~val;
    T* paux = reinterpret_cast<T*>(&val);
    return *paux;
      }
      else{
    T* paux = reinterpret_cast<T*>(&val);
    return *paux;
      }
    }
    else{ //double
      uint64_t val = 0;
      if(x == y){
    val = ~val;
    T* paux = reinterpret_cast<T*>(&val);
    return *paux;
      }
      else{
        T* paux = reinterpret_cast<T*>(&val);
        return *paux;
      }
    }
  }
  typename std::enable_if<std::is_integral<T>::value, T>::type
  operator() (const T& x, const T& y) const {
    return (x==y) ? ~((T)(0)) : ((T)(0));
  }
};

错误代码:

clases.cpp:66:3: error: ‘typename std::enable_if<std::is_integral<_Tp>::value, T>::type eq<T>::operator()(const T&, const T&) const’ cannot be overloaded
   operator() (const T& x, const T& y) const {
   ^
clases.cpp:38:3: error: with ‘typename std::enable_if<std::is_floating_point<_Tp>::value, T>::type eq<T>::operator()(const T&, const T&) const’
   operator() (const T& x, const T& y) const {

1 个答案:

答案 0 :(得分:6)

SFINAE仅在模板参数位于模板的直接上下文中时发生。对此的一个简单修复是使用默认参数将operator()函数转换为模板函数:

template <class T> struct eq {
  template<typename U=T>
  typename std::enable_if<std::is_floating_point<U>::value, U>::type
  operator() (const T& x, const T& y) const {
    //...
  }
  template <typename U=T>
  typename std::enable_if<std::is_integral<U>::value, U>::type
  operator() (const T& x, const T& y) const {
    //...
  }
};

或许稍微更清洁的解决方案是提供eq的两个部分特化;一个用于浮点类型,一个用于整数类型:

template <class T, typename=void> struct eq;

template <class T>
struct eq<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
  T operator() (const T& x, const T& y) const {
    //...
  }
};

template <class T>
struct eq<T, typename std::enable_if<std::is_integral<T>::value>::type> {
  T operator() (const T& x, const T& y) const {
    //...
  }
};