В чем причина std:: chrono:: duration отсутствие немедленного манипулирования счетчиком? - программирование
Подтвердить что ты не робот

В чем причина std:: chrono:: duration отсутствие немедленного манипулирования счетчиком?

Предположим, что

#include <chrono>
#include <iostream>
#include <ctime>

namespace Ratios { typedef std::ratio<60*60*24,1> Days; }

typedef std::chrono::system_clock Clock;
typedef Clock::time_point TimePoint;

И наш main выглядит как

int main(int argc, char *argv[])
{
    // argc check left out for brevity
    const Clock::rep d = static_cast<Clock::rep>(std::atoi(argv[1]));
    // Right now
    TimePoint now = Clock::now();
    // Start with zero days
    auto days = std::chrono::duration<Clock::rep, Ratios::Days>::zero();

    // Now we'd like to add d to the days
    days += d; // Error!
    days.count() = d; // Error!
    days = days + d; // Error!
    days += std::chrono::duration<Clock::rep, Ratios::Days>(d); // Okay
    days = days + std::chrono::duration<Clock::rep, Ratios::Days>(d); // Okay

    days *= d; // Why is this okay?
    days %= d; // And this too?

    TimePoint later = now + days;

    return 0;
}

В чем причина запрета пользователю напрямую манипулировать duration?

4b9b3361

Ответ 1

Это делается для того, чтобы заставить вас придерживаться строго типизированных значений, а не произвольных значений.

Bjarne Stroustrup имеет примеры такого поведения в "языке программирования С++" (4-е изд., 35.2.1, стр. 1011):


"Период - это единичная система, поэтому нет значения = или +=, принимающего равное значение. Это будет означать, что добавление 5 неизвестного блока SI к длине в метрах. Рассмотрим:

duration<long long, milli> d1{7}; // 7 milliseconds
d1 += 5; // error
[...]

Что означали бы здесь? 5 секунд? 5 миллисекунд? [...] Если вы знаете, что вы имеете в виду, будьте откровенны в этом. Например:

d1 += duration<long long, milli>{5}; //OK: milliseconds"

Ответ 2

Обоснование заключается в поддержании целостности единицы времени, которую представляет duration.

Вы можете думать о rep как о единицах меньше. Но duration имеет единицу времени. Можно добавить и вычесть секунды в/из секунд. Но нельзя добавить секунды и единицы меньше, не делая выражение двусмысленным и нарушая алгебру единиц.

При этом один может умножать и делить единицу времени на скалярную (без единицы) величину, и результат все равно является единицей времени. Эта библиотека представляет только единицы времени до первой мощности или нулевой мощности. Единица времени, поднятая до нулевой мощности, является скаляром и представлена ​​ rep. Единицы времени также могут иметь мощность 2 или более и отрицательные мощности. Однако эта библиотека не представляет такие единицы.

При добавлении двух величин единицы должны быть одинаковыми.

При умножении или делении двух величин формируется новый блок (например, км/ч). Когда количества одних и тех же единиц умножаются, их экспоненты добавляются (например, sec * sec == sec ^ 2). Когда количества одних и тех же единиц делятся, их показатели вычитаются (например, sec/sec == sec ^ 0 == скаляр).

Библиотека std::chrono::duration является последовательным подмножеством библиотеки физических величин, которая обрабатывает только единицы времени и только те единицы времени, где показатели равны 0 и 1.

Ответ 3

days += d; // Error!

Это связано с тем, что переменная days находится в единицах 86 400 секунд, а переменная d не имеет единицы измерения. Результат добавления количества единицы в безразмерный скаляр не определяется при стандартном анализе размеров.

days *= d; // Why is this okay?
days %= d; // And this too?

Поскольку умножение и деление величин на единичные скаляры не имеет смысла. Умножение 2 секунд на 2 приводит к 4 секундам.

Рассмотрим умножение на 2 секунды на 3 секунды; результатом является величина 6 с единицей "квадрат секунд". Конечно, chrono::duration не является полной библиотекой единиц, поэтому вы не можете иметь единицы, такие как квадрат времени, но библиотеки, такие как boost.units, будут поддерживать это.

Ответ 4

Я бы предположил, что это делается, чтобы заставить вас подумать о том, какие единицы продолжительности вы хотите добавить/вычесть. Это также мешает вам делать какие-либо предположения о том, в каких единицах находятся часы.