Was ist der Unterschied zwischen chrono :: month und chrono :: month


105

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:


129

Ja, es kann verwirrend sein, beides zu haben monthund monthsdiese 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::durationTypen sind Plural:

  • nanoseconds
  • microseconds
  • milliseconds
  • seconds
  • minutes
  • hours
  • days
  • weeks
  • months
  • years

So monthsist ein chrono::durationTyp :

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 monthund monthsreflektieren 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 monthund monthssind 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 dayund days. Und zwischen yearund 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.


Ist es garantiert wahr, July == July + months(12*x)unabhängig von x? Auch wenn x INT_MAX ist?
PiotrNycz

3
Fast. Wenn 12*xSie überlaufen, haben Sie genau dort ein undefiniertes Verhalten (bevor der monthsKonstruktor ausgeführt wird). Wenn der Wert von monthsjedoch 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).
Howard Hinnant

Sie haben Ihre Frage 17:58 gestellt und beantworten sie auch um 17:58?
Dejoma

2
Es ist nicht nur in Ordnung , Ihre eigene Frage zu beantworten, es wird auch ausdrücklich empfohlen : stackoverflow.blog/2011/07/01/… , stackoverflow.com/help/self-answer
Howard Hinnant
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.