Was ist der Unterschied zwischen den C ++ 20 Chrono Typen / Werten month{7}
und months{7}
? Ist es nicht verwirrend, zwei so ähnliche Namen zu haben?
Was ist der Unterschied zwischen den C ++ 20 Chrono Typen / Werten month{7}
und months{7}
? Ist es nicht verwirrend, zwei so ähnliche Namen zu haben?
Antworten:
Ja, es kann verwirrend sein, beides zu haben month
und months
diese Bibliothek zum ersten Mal zu sehen. Es gibt jedoch konsistente Namenskonventionen in dieser Bibliothek, um diese Verwirrung zu verringern. Der Vorteil besteht in einer klaren Trennung der verschiedenen Semantiken unter Beibehaltung kurzer intuitiver Namen.
months
Alle "vordefinierten" chrono::duration
Typen sind Plural:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
So months
ist ein chrono::duration
Typ :
unter Verwendung von Monaten = Dauer < vorzeichenbehafteter ganzzahliger Typ von mindestens 20 Bits , ratio_divide <Jahre :: Periode, Verhältnis <12> >>;
Und es ist genau 1 / 12 von years
.
static_assert(12*months{1} == years{1});
Sie können es wie folgt ausdrucken:
cout << months{7} << '\n';
Und die Ausgabe ist:
7[2629746]s
Dies entspricht 7 Einheiten von 2.629.746 Sekunden. Es stellt sich heraus, dass 2.629.746 Sekunden die durchschnittliche Länge des Monats im Zivilkalender sind. Anders ausgedrückt:
static_assert(months{1} == 2'629'746s);
(Die genaue Anzahl ist nicht besonders wichtig, außer um Bar-Wetten zu gewinnen.)
month
month
(Singular) auf der anderen Seite ist nicht ein chrono::duration
. Es ist eine kalendarische Spezifizierer für einen Monat des Jahres in den zivilen Kalender. Oder:
static_assert(month{7} == July);
Dies kann verwendet werden, um ein Datum wie das folgende zu bilden:
auto independence_day = month{7}/4d/2020y;
Die Algebra month
und months
reflektieren diese unterschiedlichen Semantiken. Zum Beispiel ist "Juli + Juli" unsinnig und daher ein Fehler bei der Kompilierung:
auto x = month{7} + month{7};
~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
Das macht aber durchaus Sinn:
auto constexpr x = month{7} + months{7};
static_assert(x == February);
Und das:
auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
Und doch:
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
Dh month
und months
sind nicht nur ungleich, sie sind nicht einmal vergleichbar. Es sind Äpfel und Orangen, wenn Sie sich für Fruchtanalogien interessieren. ;-);
Es gibt eine ähnliche Beziehung zwischen day
und days
. Und zwischen year
und years
.
Wenn es Plural ist, ist es a
chrono::duration
.
Und nur <chrono>
die Typensicherheit hilft Ihnen sicherzustellen, dass diese beiden semantisch unterschiedlichen und dennoch ähnlichen Konzepte in Ihrem Code nicht miteinander verwechselt werden.
12*x
Sie überlaufen, haben Sie genau dort ein undefiniertes Verhalten (bevor der months
Konstruktor ausgeführt wird). Wenn der Wert von months
jedoch ein Vielfaches von 12 ist (positiv oder negativ), dann ist die Addition (oder Subtraktion) im Wesentlichen ein No-Op. Sie würden das gleiche bekommen wie July == July + years(x)
.
July == July + months(12*x)
unabhängig von x? Auch wenn x INT_MAX ist?