В чем разница между типами / значениями хронографов C ++ 20 month{7}
и months{7}
? Разве не сбивает с толку два таких похожих имени?
Да, это может сбивать с толку , чтобы иметь как month
и months
при первом возникновении этой библиотеки. Однако в этой библиотеке есть согласованные соглашения об именах, которые помогают уменьшить эту путаницу. И преимущество заключается в четком разделении отдельной семантики при сохранении коротких интуитивно понятных имен.
months
Все "предопределенные" chrono::duration
типы имеют множественное число:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
Так months
это chrono::duration
тип :
используя месяцы = продолжительность < целочисленный тип со знаком длиной не менее 20 бит , ratio_divide <годы :: период, коэффициент <12> >>;
И это именно 1 / +12 о years
.
static_assert(12*months{1} == years{1});
Распечатать его можно так:
cout << months{7} << '\n';
И вывод:
7[2629746]s
Это означает 7 единиц по 2629746 единиц. Оказывается, 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;
Алгебра month
и months
отражает эту разную семантику. Например, «июль + июль» не имеет смысла и, следовательно, является ошибкой времени компиляции:
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? Даже если x является INT_MAX?12*x
переполнение, у вас тут же неопределенное поведение (доmonths
запуска конструктора). Однако, если значениеmonths
кратно 12 (положительному или отрицательному), то да, сложение (или вычитание) по существу не работает. Вы получите то же самое, что иJuly == July + years(x)
.