为什么我不能使用operator<()比较chrono::weekday类型的值?

6
在新的C++20版本中,<chrono>头文件中引入了std::chrono::weekday类型。为什么我不能使用operator<比较weekday并对它们进行排序?
auto wd1 = Wednesday;
auto wd2 = Thursday;
if (wd1 < wd2)  // compile-time error
{
    // do something
}

test.cpp:14:13: error: invalid operands to binary expression (std::chrono::weekday and 
std::chrono::weekday)
if (wd1 < wd2)
    ~~~ ^ ~~~

星期三不比星期四少,对吗?

1个回答

14
<chrono>的视图中,没有Wednesday小于ThursdayThursday - Wednesday确实等于days{1}。然而,Wednesday - Thursday等于days{6},而不是days{-1}
在现代文化中,有关一周第一天是哪一天存在争议<chrono>库认为我们不必就一周第一天达成共识。我们可以在没有这种协议的情况下对一周中的日期进行有意义的计算。
为了方便这样的计算,<chrono>将工作日视为一个独立的日历,每7天重复一次,七个周期之间完全没有区别。星期一跟随星期日,星期四跟随星期三,星期日跟随星期六。它是一个没有开始和结束的循环范围,包含七个值。
作为实际问题,星期几有两种流行的整数编码方式:
  1. C将[Sunday, Saturday]编码为[0, 6]。
  2. ISO将[Monday, Sunday]编码为[1, 7]。
<chrono>通过在weekday构造函数中接受[0, 7]来承认这一点,分别表示SundayMondayTuesdayWednesdayThursdayFridaySaturdaySunday。而为了实现反向转换,weekday有两个成员函数:
  1. c_encoding()
  2. iso_encoding()
它们根据这两个协议返回与存储的weekday相关联的整数值(对于星期日为0或7,对于星期一到星期六为1到6)。 但是,在涉及weekday的计算中,应该将std::chrono::weekday的基本编码视为不重要的细节。

std::chrono::weekday是一个由7个值组成的循环范围。没有任何一个值比其他值大。它们要么相等,要么不相等。

任意两个weekday值(比如说xy)之间的差异都代表着x领先于y的天数。这是真实的,无论你想象中的数字编码在幕后表示的是什么。

这意味着Wednesday不比Thursday小。Wednesday领先于Thursday6天,而Thursday领先于Wednesday1天。

这种设计使得计算"从这个日期开始下一个星期一是哪一天"成为可能,而不依赖于底层编码:

std::chrono::sys_days
next_monday(std::chrono::sys_days x)
{
    using namespace std::chrono;
    return x + (Monday - weekday{x});
}

在中文中: x的工作日比星期一晚了几天?将这么多天加到x上。

2
至少,Monday应该明显小于Friday。我们能不能例外一下 :-) - Barry
1
也许我们应该在工作日添加“愉悦点” :-) - Howard Hinnant
仿射解答。模块对向量空间,仿射空间对什么?但我猜Z_7是一个域,所以工作日的空间是一个仿射空间? - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接