Яка різниця між chrono :: month та chrono :: months


106

У чому різниця між типами / значеннями хронометра C ++ 20 month{7}та months{7}? Чи не бентежить наявність двох таких подібних назв?

Відповіді:


130

Так, це може заплутати наявність і того, monthі іншого monthsпри першій зустрічі з цією бібліотекою. Однак у цій бібліотеці існують послідовні правила іменування, які допомагають зменшити цю плутанину. І перевагою є чітке розділення чіткої семантики при збереженні коротких інтуїтивних назв.

months

Усі "заздалегідь визначені" chrono::durationтипи множинні:

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

Так monthsі chrono::durationтип :

використовуючи місяці = тривалість < цілочисельний тип зі знаком щонайменше 20 біт ,
                         співвідношення_ділити <роки :: період, співвідношення <12> >>;

І це саме +1 / 12 з years.

static_assert(12*months{1} == years{1});

Ви можете роздрукувати його так:

cout << months{7} << '\n';

І результат:

7[2629746]s

Це виглядає як 7 одиниць 2629746. Виявляється, 2629 746 секунд - це середня тривалість місяця за цивільним календарем. По-різному:

static_assert(months{1} == 2'629'746s);

(точна кількість не особливо важлива, за винятком виграшних барних ставок)

month

month(однина) з іншого боку не є chrono::duration. Це календарний специфікатор місяця року за цивільним календарем. Або:

static_assert(month{7} == July);

Це може бути використано для формування дати такою:

auto independence_day = month{7}/4d/2020y;

Алгебра monthта monthsвідображення цієї різної семантики. Наприклад, "липень + липень" є безглуздим, і, отже, помилка під час компіляції:

auto x = month{7} + month{7};
         ~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')

Але в цьому цілком логічно:

auto constexpr x = month{7} + months{7};
static_assert(x == February);

І це:

auto constexpr x = months{7} + months{7};
static_assert(x == months{14});

І все ж:

auto b = February == months{14};
         ~~~~~~~~ ^  ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')

Тобто monthі monthsне тільки не рівні, вони навіть не порівнянні. Це яблука та апельсини, якщо ви любите аналогію з фруктами. ;-)

Існує схожий зв’язок між dayі days. А між yearіyears .


Якщо це множина, це a chrono::duration.


І лише <chrono>типова безпека допомагає вам переконатися, що ці два семантично відмінні, але водночас подібні поняття не плутаються між собою у коді.


Чи гарантовано це буде правдою July == July + months(12*x)незалежно від х? Навіть якщо x є INT_MAX?
PiotrNycz

3
Майже. Якщо 12*xпереповнення ви маєте невизначену поведінку саме там (до monthsзапуску конструктора). Однак, якщо значення monthsкратне 12 (позитивне чи негативне), тоді так, додавання (або віднімання), по суті, є відсутністю. Ви отримаєте те саме, що July == July + years(x).
Говард Хіннант

Ви задали своє запитання о 17:58 і ви також відповідаєте на нього о 17:58?
dejoma

2
Це не тільки добре , щоб відповісти на своє запитання, він явно рекомендується: stackoverflow.blog/2011/07/01 / ... , stackoverflow.com/help/self-answer
Говард Hinnant
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.