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