Jaka jest różnica między typami / wartościami chronologicznymi C ++ 20 month{7}
a months{7}
? Czy nie jest mylące mieć dwie takie podobne nazwy?
Tak, posiadanie obu month
i months
przy pierwszym kontakcie z tą biblioteką może być mylące . Jednak w tej bibliotece obowiązują spójne konwencje nazewnictwa, które pomagają zmniejszyć to zamieszanie. Zaletą jest wyraźne oddzielenie odrębnych semantyki przy zachowaniu krótkich, intuicyjnych nazw.
months
Wszystkie „predefiniowane” chrono::duration
typy są w liczbie mnogiej:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
Więc months
jest chrono::duration
typ :
przy użyciu miesięcy = czas trwania < typ liczby całkowitej ze znakiem co najmniej 20 bitów , ratio_divide <lata :: okres, stosunek <12> >>;
I to jest dokładnie 1 / 12 z years
.
static_assert(12*months{1} == years{1});
Możesz to wydrukować w ten sposób:
cout << months{7} << '\n';
A wynik to:
7[2629746]s
To czyta się jako 7 jednostek 2629746s. Okazuje się, że 2629746 sekund to średnia długość miesiąca w kalendarzu cywilnym. Stwierdzono inaczej:
static_assert(months{1} == 2'629'746s);
(dokładna liczba nie jest szczególnie ważna, z wyjątkiem wygrywających zakładów barowych)
month
month
(liczba pojedyncza) z drugiej strony nie jest chrono::duration
. Jest to specyfikator kalendarzowy miesiąca w roku w kalendarzu cywilnym. Lub:
static_assert(month{7} == July);
Można to wykorzystać do utworzenia takiej daty:
auto independence_day = month{7}/4d/2020y;
Algebra month
i months
odzwierciedlają te różne semantyki. Na przykład „lipiec + lipiec” jest bezsensowne, a zatem stanowi błąd w czasie kompilacji:
auto x = month{7} + month{7};
~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
Ale to ma sens:
auto constexpr x = month{7} + months{7};
static_assert(x == February);
I to:
auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
I jeszcze:
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
Tj. month
I months
nie tylko nie są równe, ale nie są nawet porównywalne. To jabłka i pomarańcze, jeśli lubisz owocowe analogie. ;-)
Istnieje podobny związek między day
i days
. A między year
a years
.
Jeśli jest w liczbie mnogiej, to jest
chrono::duration
.
I <chrono>
ma tylko bezpieczeństwo typów, które pomaga zapewnić, że te dwa semantycznie różne, a jednocześnie podobne koncepcje nie zostaną pomylone ze sobą w kodzie.
July == July + months(12*x)
niezależnie od x? Nawet jeśli x jest INT_MAX?12*x
przepełnienia, masz niezdefiniowane zachowanie (przedmonths
uruchomieniem konstruktora). Jeśli jednak wartośćmonths
jest wielokrotnością 12 (dodatnia lub ujemna), to tak, dodawanie (lub odejmowanie) jest zasadniczo niedopuszczalne. Dostałbyś to samo, coJuly == July + years(x)
.