Quelle est la différence entre les types/valeurs de chronos C++20 ? month{7}
y months{7}
? N'est-il pas déroutant d'avoir deux noms aussi similaires ?
Réponse
Trop de publicités?Oui, ça peut être déroutant d'avoir les deux. month
y months
lors de la première rencontre avec cette bibliothèque. Cependant, il existe des conventions de dénomination cohérentes dans cette bibliothèque pour aider à réduire cette confusion. L'avantage est d'avoir une séparation claire des sémantiques distinctes tout en conservant des noms courts et intuitifs.
months
Tous les "prédéfinis" chrono::duration
Les types sont au pluriel :
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
Alors months
est un chrono::duration
type :
using months = duration<_signed integer type of at least 20 bits_,
ratio\_divide<years::period, ratio<12>>>;
Et c'est exactement 1 / 12 de years
.
static_assert(12*months{1} == years{1});
Vous pouvez l'imprimer comme ceci :
cout << months{7} << '\n';
Et le résultat est :
7[2629746]s
Cela se lit comme 7 unités de 2,629,746s. Il s'avère que 2,629,746 secondes est la durée moyenne d'un mois dans le calendrier civil. En d'autres termes :
static_assert(months{1} == 2'629'746s);
(le nombre exact n'est pas particulièrement important, sauf pour gagner des paris de bar)
month
month
(singulier) d'autre part est pas a chrono::duration
. Il s'agit d'un spécificateur calendaire pour un mois de l'année dans le calendrier civil. Ou :
static_assert(month{7} == July);
Cela peut être utilisé pour former une date comme celle-ci :
auto independence_day = month{7}/4d/2020y;
L'algèbre de month
y months
reflètent ces différentes sémantiques. Par exemple, "juillet + juillet" n'a aucun sens et constitue donc une erreur de compilation :
auto x = month{7} + month{7};
~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
Mais c'est parfaitement logique :
auto constexpr x = month{7} + months{7};
static_assert(x == February);
Et ceci :
auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
Et pourtant :
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
I.e. month
y months
ne sont non seulement pas égaux, mais ils ne sont même pas comparables. Ce sont des pommes et des oranges, si vous aimez les analogies avec les fruits ;-)
Il existe une relation similaire entre day
y days
. Et entre year
y years
.
Si c'est au pluriel, c'est un
chrono::duration
.
Et seulement <chrono>
possède la sécurité de type qui vous permet de vous assurer que ces deux concepts sémantiquement distincts et pourtant similaires ne sont pas confondus dans votre code.