110 votes

Quelle est la différence entre chrono::month et chrono::months ?

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 ?

137voto

Howard Hinnant Points 59526

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X