c++ - 在 C++ 20 之前的 C++ 中是否有更好的方法来定义关系运算符?

标签 c++ operators c++17 comparison-operators

编写这样的代码对我来说非常乏味

class date {
private: 
    int day, year, month;
    int comp(const date & Other) const;
public:
    date(int D, int Y, int M) : day (D), year (Y), month (M)  {}

    friend bool operator==(const date & L, const date & R) { return L.comp(R) == 0 ; }
    friend bool operator!=(const date & L, const date & R) { return L.comp(R) != 0 ; }
    friend bool operator> (const date & L, const date & R) { return L.comp(R) > 0 ; }
    friend bool operator>=(const date & L, const date & R) { return L.comp(R) >= 0 ; }
    friend bool operator< (const date & L, const date & R) { return L.comp(R) < 0 ; }
    friend bool operator<=(const date & L, const date & R) { return L.comp(R) <= 0 ; }
}

所有关系运算符的内容都是样板文件(对于每个需要它们的类来说都是相同的)。 肯定有更好的方法来完成这一切。我知道 C++ 20 提供了 spaceship 运算符,但我没有。所以我的问题是:如何避免使用早于 C++ 20 的功能的样板代码?

最佳答案

您可以使用Boost.Operators (或者自己实现这样的事情),但你仍然需要编写两个函数:

class date : public totally_ordered<date> {
private: 
    int day, year, month;
    int comp(const date & Other) ;
public:
    date(int D, int Y, int M) : day (D), year (Y), month (M)  {}

    friend bool operator==(const date & L, const date & R) { return L.comp(R) == 0 ; }
    friend bool operator< (const date & L, const date & R) { return L.comp(R) < 0 ; }
}

请注意,您通常不想使用定义 == 的模式从 == 开始的三向排序一般来说,效率会更高(例如,考虑一下字符串的情况,您立即知道不同大小的字符串不相等,但如果不实际比较任意大量的字符,您不知道 compare() 的结果是什么)。

另请注意,此方法的一个普遍问题是确定 x <= y 是否有效。定义为!(y < x)x < y || x == y 。大多数库解决方案选择前者(比较较少),尽管这在部分顺序上给出了错误的答案 - 这是<=>的动机的一部分首先。 Boost.Operators 通过还具有 partially_ordered<T> 来解决这个问题。它正确定义了 <=就这两种操作而言。

<小时/>

There must surely be a better way to do all this.

Nicol说,这就是我们添加 <=> 的原因:

class date {
private: 
    int year, month, day; // NB: I reordered these
public:
    friend auto operator<=>(const date&, const date&) = default;
};

关于c++ - 在 C++ 20 之前的 C++ 中是否有更好的方法来定义关系运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59504339/

相关文章:

c++ - 使用回溯的骑士​​之旅

c++ - C++ 中的幂函数和数组

c++ - 静态内联成员初始化顺序

c++ - 我可以 std::forward 折叠表达式中的参数吗?

c++ - 为外部 DLL 设置 OMP 线程数

c# - C# 中匿名 lambda 函数的 C++ 捕获子句等效项

javascript - 了解JavaScript逗号运算符

c++ - boost foreach 和运算符重载

javascript - 为什么 Javascript 允许非数字算术

c++ - constexpr 函数允许什么?