【发布时间】:2020-09-26 16:16:00
【问题描述】:
C++20 计时类型/值month{7} 和months{7} 有什么区别?有两个这么相似的名字是不是很混乱?
【问题讨论】:
C++20 计时类型/值month{7} 和months{7} 有什么区别?有两个这么相似的名字是不是很混乱?
【问题讨论】:
是的,当第一次遇到这个库时,同时拥有 month 和 months 可能会令人困惑。然而,这个库中有一致的命名约定,以帮助减少这种混淆。这样做的好处是可以清楚地区分不同的语义,同时保留简短直观的名称。
months所有“预定义”chrono::duration 类型都是复数:
nanosecondsmicrosecondsmillisecondssecondsminuteshoursdaysweeksmonthsyears所以months 是chrono::duration type:
它正好是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);
(确切的数字不是特别重要,除了赢得酒吧赌注)
monthmonth(单数)不是chrono::duration。它是民用日历中一年中一个月的日历说明符。或者:
static_assert(month{7} == July);
这可以用来形成这样的日期:
auto independence_day = month{7}/4d/2020y;
month 和 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});
然而:
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)?即使 x 是 INT_MAX?
12*x 溢出,你就会有未定义的行为(在months 构造函数运行之前)。但是,如果 months 的值是 12 的倍数(正或负),那么是的,加法(或减法)本质上是无操作的。你会得到和July == July + years(x)一样的东西。