C++20的chrono类型/值 month{7}
和 months{7}
有什么区别? 有两个如此相似的名称不会让人感到困惑吗?
C++20的chrono类型/值 month{7}
和 months{7}
有什么区别? 有两个如此相似的名称不会让人感到困惑吗?
当第一次接触这个库时,同时拥有month
和months
可能会令人困惑。但是,该库中有一致的命名约定,以帮助减少这种混淆。好处是保持清晰分离的显著语义,同时保留简短直观的名称。
months
所有“预定义”的chrono::duration
类型都是复数形式:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
因此,months
是一个chrono::duration
类型:
using months = duration<至少为20位的有符号整数类型, ratio_divide<years::period, ratio<12>>>;
它恰好是years
的1/12。
static_assert(12*months{1} == years{1});
您可以这样打印:
cout << months{7} << '\n';
输出结果为:
7[2629746]s
这可以理解为7个长度为2,629,746秒的时间单位。事实证明,2,629,746秒是公历中一个月的平均长度。换句话说:
static_assert(months{1} == 2'629'746s);
(这个确切的数字并不特别重要,除了在赢得酒吧赌注时)
月份
月份
(单数)则不是 chrono::duration
。它是一个民用历法年度中某个月份的日期指定符。或者说:
static_assert(month{7} == July);
这可以用来形成如下日期:
auto independence_day = month{7}/4d/2020y;
month
和months
的代数反映了它们不同的语义。例如,“七月+七月”是无意义的,因此会在编译时出错:
month
和months
的代数反映了它们不同的语义。例如,“七月+七月”是无意义的,因此会在编译时出错:
auto x = month{7} + month{7};
~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
但这非常合理:
auto constexpr x = month{7} + months{7};
static_assert(x == February);
还有这个:
auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
然而:
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
例如,month
和months
不仅不相等,它们甚至不能比较。如果您喜欢水果类比,它们就像是苹果和橙子。
day
和days
之间也有类似的关系。以及year
和years
之间。
如果是复数,则为
chrono::duration
。
只有<chrono>
才具有类型安全性,可帮助您确保代码中这两个语义上不同但相似的概念不会混淆。
July == July + months(12*x)
是否保证为真? - PiotrNycz12*x
溢出,那么你在months
构造函数运行之前就已经有了未定义的行为。但是,如果months
的值是12的倍数(正或负),那么加法(或减法)基本上是无操作的。你会得到与July == July + years(x)
相同的结果。 - Howard Hinnant