chrono::month和chrono::months之间有什么区别?

110

C++20的chrono类型/值 month{7}months{7} 有什么区别? 有两个如此相似的名称不会让人感到困惑吗?

1个回答

137

当第一次接触这个库时,同时拥有monthmonths可能会令人困惑。但是,该库中有一致的命名约定,以帮助减少这种混淆。好处是保持清晰分离的显著语义,同时保留简短直观的名称。

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>>>;

它恰好是years1/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;

monthmonths的代数反映了它们不同的语义。例如,“七月+七月”是无意义的,因此会在编译时出错:

monthmonths的代数反映了它们不同的语义。例如,“七月+七月”是无意义的,因此会在编译时出错:

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')

例如,monthmonths不仅不相等,它们甚至不能比较。如果您喜欢水果类比,它们就像是苹果和橙子。

daydays之间也有类似的关系。以及yearyears之间。


如果是复数,则为chrono::duration


只有<chrono>才具有类型安全性,可帮助您确保代码中这两个语义上不同但相似的概念不会混淆。


无论x是INT_MAX,July == July + months(12*x)是否保证为真? - PiotrNycz
4
几乎一样。如果12*x溢出,那么你在months构造函数运行之前就已经有了未定义的行为。但是,如果months的值是12的倍数(正或负),那么加法(或减法)基本上是无操作的。你会得到与July == July + years(x)相同的结果。 - Howard Hinnant
1
你在 17:58 提出了问题,然后在同一时间回答了自己的问题吗? - dejoma
5
回答自己的问题不仅是可以的,而且明确地受到鼓励:https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/ , https://stackoverflow.com/help/self-answer - Howard Hinnant

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