为什么我不能将 chrono::weekday 与 operator<() 进行比较?
Why can I not compare chrono::weekday's with operator<()?
在新的 C++20 <chrono>
头文件中有一个 std::chrono::weekday
类型。为什么我不能将 weekday
与 operator<
进行比较,从而对它们进行排序?
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)
~~~ ^ ~~~
星期三不是比星期四少吗?
在<chrono>
看来,没有Wednesday
不小于Thursday
。
Thursday - Wednesday
确实等于 days{1}
。但是 Wednesday - Thursday
等于 days{6}
,而不是 days{-1}
。
在现代文化中,有disagreement about which day is the first day of the week。 <chrono>
图书馆认为我们不必就哪一天是一周的第一天达成一致。我们可以在没有这种约定的情况下对星期几进行有意义的计算。
为了便于进行此类计算,<chrono>
将工作日视为一个独立的日历,每 7 天重复一次,7 天周期之间绝对没有区别。星期一在星期天之后,星期四在星期三之后,星期天在星期六之后。它是七个值的循环范围,没有开始也没有结束。
作为一个实际问题,有两种流行的工作日整数值编码:
- C 将 [Sunday, Saturday] 编码为 [0, 6]。
- ISO 将 [Monday, Sunday] 编码为 [1, 7]。
<chrono>
通过接受 weekday
构造函数中的 [0, 7] 表示 Sunday
、Monday
、Tuesday
、[=12 来承认这一点=]、Thursday
、Friday
、Saturday
、Sunday
。并启用反向转换 weekday
有两个成员函数:
c_encoding()
iso_encoding()
其中 return 根据这两个协议与存储的 weekday
关联的整数值(周日为 0 或 7,周一至周六为 1 至 6)。
但是,std::chrono::weekday
的底层编码对于涉及 weekday
.
的计算应被视为不重要的细节
std::chrono::weekday
是 7 个值的循环范围。没有任何值大于任何其他值。它们要么相等,要么不相等。
任何两个 weekday
值之间的差异(比如 x
和 y
)导致 days
x
的数量领先于 y
.这是真的,无论你想象的是什么数字编码在幕后代表 weekday
。
这意味着Wednesday
不小于Thursday
。 Wednesday
比Thursday
早6天,Thursday
比Wednesday
早1天。
这种设计可以在不依赖底层编码的情况下进行诸如“从这个日期开始的下一个星期一是什么时候”之类的计算:
std::chrono::sys_days
next_monday(std::chrono::sys_days x)
{
using namespace std::chrono;
return x + (Monday - weekday{x});
}
英文:
x
的工作日比星期一晚多少天?将那么多天添加到 x
。
在新的 C++20 <chrono>
头文件中有一个 std::chrono::weekday
类型。为什么我不能将 weekday
与 operator<
进行比较,从而对它们进行排序?
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)
~~~ ^ ~~~
星期三不是比星期四少吗?
在<chrono>
看来,没有Wednesday
不小于Thursday
。
Thursday - Wednesday
确实等于 days{1}
。但是 Wednesday - Thursday
等于 days{6}
,而不是 days{-1}
。
在现代文化中,有disagreement about which day is the first day of the week。 <chrono>
图书馆认为我们不必就哪一天是一周的第一天达成一致。我们可以在没有这种约定的情况下对星期几进行有意义的计算。
为了便于进行此类计算,<chrono>
将工作日视为一个独立的日历,每 7 天重复一次,7 天周期之间绝对没有区别。星期一在星期天之后,星期四在星期三之后,星期天在星期六之后。它是七个值的循环范围,没有开始也没有结束。
作为一个实际问题,有两种流行的工作日整数值编码:
- C 将 [Sunday, Saturday] 编码为 [0, 6]。
- ISO 将 [Monday, Sunday] 编码为 [1, 7]。
<chrono>
通过接受 weekday
构造函数中的 [0, 7] 表示 Sunday
、Monday
、Tuesday
、[=12 来承认这一点=]、Thursday
、Friday
、Saturday
、Sunday
。并启用反向转换 weekday
有两个成员函数:
c_encoding()
iso_encoding()
其中 return 根据这两个协议与存储的 weekday
关联的整数值(周日为 0 或 7,周一至周六为 1 至 6)。
但是,std::chrono::weekday
的底层编码对于涉及 weekday
.
std::chrono::weekday
是 7 个值的循环范围。没有任何值大于任何其他值。它们要么相等,要么不相等。
任何两个 weekday
值之间的差异(比如 x
和 y
)导致 days
x
的数量领先于 y
.这是真的,无论你想象的是什么数字编码在幕后代表 weekday
。
这意味着Wednesday
不小于Thursday
。 Wednesday
比Thursday
早6天,Thursday
比Wednesday
早1天。
这种设计可以在不依赖底层编码的情况下进行诸如“从这个日期开始的下一个星期一是什么时候”之类的计算:
std::chrono::sys_days
next_monday(std::chrono::sys_days x)
{
using namespace std::chrono;
return x + (Monday - weekday{x});
}
英文:
x
的工作日比星期一晚多少天?将那么多天添加到 x
。