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

How*_*ant 103 c++ c++-chrono c++20

C++20 计时类型/值month{7}months{7}? 有两个如此相似的名字是不是很混乱?

How*_*ant 129

是的,当第一次遇到这个库时,同时拥有month和可能会令人困惑months。然而,这个库中有一致的命名约定来帮助减少这种混淆。好处是在保留简短的直观名称的同时,清楚地分离了不同的语义。

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});
Run Code Online (Sandbox Code Playgroud)

你可以像这样打印出来:

cout << months{7} << '\n';
Run Code Online (Sandbox Code Playgroud)

输出是:

7[2629746]s
Run Code Online (Sandbox Code Playgroud)

这读取为 2,629,746 的 7 个单位。事实证明,2,629,746 秒是公历中一个月的平均长度。不同的说法:

static_assert(months{1} == 2'629'746s);
Run Code Online (Sandbox Code Playgroud)

(确切的数字不是特别重要,除了赢得酒吧投注)

month

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

static_assert(month{7} == July);
Run Code Online (Sandbox Code Playgroud)

这可用于形成这样的日期:

auto independence_day = month{7}/4d/2020y;
Run Code Online (Sandbox Code Playgroud)

的代数monthmonths反映了这些不同的语义。例如“July + July”是无意义的,因此是编译时错误:

auto x = month{7} + month{7};
         ~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
Run Code Online (Sandbox Code Playgroud)

但这完全有道理:

auto constexpr x = month{7} + months{7};
static_assert(x == February);
Run Code Online (Sandbox Code Playgroud)

和这个:

auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
Run Code Online (Sandbox Code Playgroud)

但是:

auto b = February == months{14};
         ~~~~~~~~ ^  ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
Run Code Online (Sandbox Code Playgroud)

monthmonths不仅不相等,它们甚至没有可比性。如果你喜欢水果类比的话,它们就是苹果和橙子。;-)

day和之间也有类似的关系days。和之间yearyears


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


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

  • 几乎。如果 `12*x` 溢出,你就会有未定义的行为(在 `months` 构造函数运行之前)。然而,如果“months”的值是 12 的倍数(正数或负数),那么加法(或减法)本质上是无操作。你会得到与“July == July +years(x)”相同的结果。 (3认同)
  • 不仅可以回答自己的问题,而且明确鼓励:https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/,https: //stackoverflow.com/help/self-answer (3认同)