首页 > 解决方案 > 使用 enable_if 添加重载运算符 ==

问题描述

我有一个工作模板类点,其重载为operator==.

由于浮点比较,我试图enable_if为浮点添加第二个重载以使用几乎相等的函数。

这是我的尝试:

template<typename T>
class Point2D
{
public:
   Point2D(T x, T y);

   Point2D& operator= (const Point2D& point);
   bool     operator==(const Point2D& point) const;
   bool     operator!=(const Point2D& point) const;
};

template<typename T>
Point2D<T>::Point2D(T x, T y) : x_(x), y_(y)
{
}

template<typename T>
Point2D<T>& Point2D<T>::operator=(const Point2D& point)
{
   if(this != &point)
   {
      x_ = point.x_;
      y_ = point.y_;
   }

   return *this;
}

template<typename T>
bool Point2D<T>::operator==(const Point2D& point) const
{
   return (x_ == point.x_) && (y_ == point.y_);
}

template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
Point2D<T>::operator==(const Point2D& point) const
{
   return Traits::almost_equal(x_, point.x_) &&
          Traits::almost_equal(y_, point.y_);
}

笔记:

编译器给我的错误是

error: prototype for typename std::enable_if<std::is_floating_point<_Tp>::value, bool>::type Point2D<T>::operator==(const Point2D<T>&) const
  does not match any in class Point2D<T>
  Point2D<T>::operator==(const Point2D& point) const
  ^

error: candidate is: bool Point2D<T>::operator==(const Point2D<T>&)
const bool Point2D<T>::operator==(const Point2D& point) const
      ^

我不明白错误指的是什么。

标签: c++c++11templatesoperator-overloadingenable-if

解决方案


错误很明显 - 您的定义与您的声明不匹配。您的原型和定义都需要完全相同enable_if。此外,您enable_if将无法工作,因为它需要在替换(SFINAE)期间发生。

为了使事情更具可读性,您可以定义别名并使用尾随返回类型

template<typename T>
class Point2D
{
   template <typename U>
   using EnableIfFloat = 
      typename std::enable_if<std::is_floating_point<U>::value, bool>::type;

public:
   Point2D(T x, T y);

   template <typename U = T>
   auto operator==(const Point2D& point) const -> EnableIfFloat<U>&;
   bool operator==(const Point2D& point) const;
   bool operator!=(const Point2D& point) const;
};

定义:

template<typename T>
template<typename U>
auto Point2D<T>::operator==(const Point2D& point) const -> EnableIfFloat<U>&
{
   return Traits::almost_equal(x_, point.x_) &&
          Traits::almost_equal(y_, point.y_);
}

推荐阅读