chrono :: month和chrono :: months有什么区别


106

C ++ 20 chrono类型/值month{7}和之间有什么区别months{7}?拥有两个这样的相似名称是否会引起混淆?

Answers:


130

是的,同时拥有monthmonths第一次遇到该库时可能会造成混淆。但是,此库中有一致的命名约定,以帮助减少这种混淆。这样做的好处是可以清楚区分不同的语义,同时保留简短的直观名称。

months

所有“预定义”chrono::duration类型都是复数:

  • nanoseconds
  • microseconds
  • milliseconds
  • seconds
  • minutes
  • hours
  • days
  • weeks
  • months
  • years

所以months是一个chrono::duration类型

使用months = duration <至少20位的有符号整数类型,
                         ratio_divide <years :: period,ratio <12 >>>;

而正是1 / 12个years

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

(确切的数字不是很重要,除了赢得下注的小注)

month

month在另一方面(单数)是一个chrono::duration。它是民用日历中一年中一个月的日历说明符。要么:

static_assert(month{7} == July);

这可以用来形成这样的日期:

auto independence_day = month{7}/4d/2020y;

的代数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不仅是不相等,他们甚至不具有可比性。如果您喜欢类比的话,它们是苹果和橙子。;-)

day和之间存在类似的关系days。在year和之间years


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


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


July == July + months(12*x)不论x都可以保证为真 吗?即使x是INT_MAX?
PiotrNycz

3
几乎。如果12*x溢出,则那里有未定义的行为(在months构造函数运行之前)。但是,如果的值months是12的倍数(正或负),则是的加法(或减法)本质上是空运算。您将获得与相同的结果July == July + years(x)
Howard Hinnant

您在17:58问了您的问题,您也在17:58回答了吗?
dejoma

2
它不仅确定回答你自己的问题,明确鼓励:stackoverflow.blog/2011/07/01/...stackoverflow.com/help/self-answer
霍华德Hinnant(欣南特)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.