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

c++ template operator overloading std::enable_if

本文关键字:enable if std 重载 运算符 C++      更新时间:2023-10-16

我在编译此模板时遇到问题。我只想创建一个运算符,其功能取决于数据类型(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 {

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 {
    //...
  }
};