В чем причина того, что в 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 напрямую?

4 ответа

Решение

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

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


" Период представляет собой единичную систему, поэтому нет = или же += принимая простую ценность. Разрешение это будет похоже на разрешение добавления 5 неизвестной единицы СИ на длину в метрах. Рассматривать:

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

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

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

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

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

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

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

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

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

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 будут поддерживать это.

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

Другие вопросы по тегам