У чому різниця між типами / значеннями хронометра C ++ 20 month{7}та months{7}? Чи не бентежить наявність двох таких подібних назв?
У чому різниця між типами / значеннями хронометра C ++ 20 month{7}та months{7}? Чи не бентежить наявність двох таких подібних назв?
Відповіді:
Так, це може заплутати наявність і того, monthі іншого monthsпри першій зустрічі з цією бібліотекою. Однак у цій бібліотеці існують послідовні правила іменування, які допомагають зменшити цю плутанину. І перевагою є чітке розділення чіткої семантики при збереженні коротких інтуїтивних назв.
monthsУсі "заздалегідь визначені" chrono::durationтипи множинні:
nanosecondsmicrosecondsmillisecondssecondsminuteshoursdaysweeksmonthsyearsТак monthsі chrono::durationтип :
використовуючи місяці = тривалість < цілочисельний тип зі знаком щонайменше 20 біт ,
співвідношення_ділити <роки :: період, співвідношення <12> >>;
І це саме +1 / 12 з years.
static_assert(12*months{1} == years{1});
Ви можете роздрукувати його так:
cout << months{7} << '\n';
І результат:
7[2629746]s
Це виглядає як 7 одиниць 2629746. Виявляється, 2629 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відображення цієї різної семантики. Наприклад, "липень + липень" є безглуздим, і, отже, помилка під час компіляції:
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 .
Якщо це множина, це a
chrono::duration.
І лише <chrono>типова безпека допомагає вам переконатися, що ці два семантично відмінні, але водночас подібні поняття не плутаються між собою у коді.
12*xпереповнення ви маєте невизначену поведінку саме там (до monthsзапуску конструктора). Однак, якщо значення monthsкратне 12 (позитивне чи негативне), тоді так, додавання (або віднімання), по суті, є відсутністю. Ви отримаєте те саме, що July == July + years(x).
July == July + months(12*x)незалежно від х? Навіть якщо x є INT_MAX?