是的,两者兼而有之可能会令人困惑month
and months
当第一次遇到这个库时。然而,该库中有一致的命名约定,有助于减少这种混乱。这样做的好处是可以清楚地分离不同的语义,同时保留简短直观的名称。
months
全部“预定义”chrono::duration
类型是复数:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
So months
is a chrono::duration type http://eel.is/c++draft/time.syn:
using months = duration<signed integer type of at least 20 bits,
ratio_divide<years::period, ratio<12>>>;
And it is exactly 1/12 of 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
(单数)另一方面是not a chrono::duration
。它是一个历法说明符民历中一年中的一个月。或者:
static_assert(month{7} == July);
这可以用来形成这样的日期:
auto independence_day = month{7}/4d/2020y;
的代数month
and months
反映这些不同的语义。例如,“July + July”是无意义的,因此会出现编译时错误:
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});
And yet:
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
I.e. month
and months
不仅不相等,甚至没有可比性。如果你喜欢用水果做类比的话,它们就是苹果和橙子。 ;-)
之间也存在类似的关系day
and days
。而之间year
and years
.
如果是复数,则为chrono::duration
.
并且只有<chrono>
具有类型安全性,可帮助您确保这两个语义上不同但相似的概念不会在代码中相互混淆。