std::chrono::duration целочисленные трудности

У меня есть этот простой таймер-секундомер шаблона, который я планирую использовать в своем следующем проекте, всякий раз, когда я создаю экземпляр этого класса, используя «Timer‹ float>», все работает нормально, однако, если я использую «Timer‹ int>», я получаю ошибки.

timer.h(18): ошибка C2440: '': невозможно преобразовать из 'std::chrono::duration‹_Rep,_Period>' в 'std::chrono::duration‹_Rep,_Period>'

Я не знаю, почему это происходит, вся помощь приветствуется, заранее спасибо!

template< typename type > class Timer
{

public:

    void Start(){ m_Start = m_Time.now(); }
    void Reset(){ m_Start = m_Time.now(); m_Split = m_Start; }
    void Split(){ m_Split = m_Time.now(); }

    type HoursSinceStart()          { return std::chrono::duration< type, std::ratio< 3600 > >( m_Time.now() - m_Start ).count(); }
    type MinutesSinceStart()        { return std::chrono::duration< type, std::ratio< 60 > >( m_Time.now() - m_Start ).count(); }
    type SecondsSinceStart()        { return std::chrono::duration< type, std::ratio< 1 > >( m_Time.now() - m_Start ).count(); }
    type MilliSecondsSinceStart()   { return std::chrono::duration< type, std::milli >( m_Time.now() - m_Start ).count(); }
    type MicroSecondsSinceStart()   { return std::chrono::duration< type, std::micro >( m_Time.now() - m_Start ).count(); }
    type NanoSecondsSinceStart()    { return std::chrono::duration< type, std::nano >( m_Time.now() - m_Start ).count(); }

    type HoursSinceSplit()          { return std::chrono::duration< type, std::ratio< 3600 > >( m_Time.now() - m_Split ).count(); }
    type MinutesSinceSplit()        { return std::chrono::duration< type, std::ratio< 60 > >( m_Time.now() - m_Split ).count(); }
    type SecondsSinceSplit()        { return std::chrono::duration< type, std::ratio< 1 > >( m_Time.now() - m_Split ).count(); }
    type MilliSecondsSinceSplit()   { return std::chrono::duration< type, std::milli >( m_Time.now() - m_Split ).count(); }
    type MicroSecondsSinceSplit()   { return std::chrono::duration< type, std::micro >( m_Time.now() - m_Split ).count(); }
    type NanoSecondsSinceSplit()    { return std::chrono::duration< type, std::nano >( m_Time.now() - m_Split ).count(); }

private:

    std::chrono::high_resolution_clock m_Time;

    std::chrono::high_resolution_clock::time_point m_Start;
    std::chrono::high_resolution_clock::time_point m_Split;
};

person Patrick le Duc    schedule 19.03.2015    source источник
comment
std::chrono уже определяет hours minutes seconds и т. д., вам не нужно определять их самостоятельно.   -  person Mgetz    schedule 19.03.2015
comment
Спасибо, я изменил свой код, теперь он использует std::chrono::‹durationtype› во всех функциях для удобочитаемости!   -  person Patrick le Duc    schedule 19.03.2015


Ответы (1)


Библиотека chrono пытается уберечь вас от случайной потери информации во время преобразования единиц измерения. Например, всегда можно преобразовать minutes в nanoseconds, потому что nanoseconds всегда может точно представлять любое количество minutes.

Но nanoseconds не будет так легко конвертироваться в minutes, потому что это преобразование "с потерями". Преобразование не будет точным, оно будет иметь ошибку усечения (округления). Если вы действительно хотите такого преобразования, вы должны четко указать это. Это то, для чего предназначен std::chrono::duration_cast. Например:

minutes m = duration_cast<minutes>(ns);

Это говорит о преобразовании nanoseconds в minutes и усечении до нуля, когда у вас останется nanoseconds.

Эта «подушка безопасности» применима только к интегральным представлениям (например, int). Когда вы используете длительности с плавающей запятой, допускается неявное преобразование из nanoseconds в minutes, потому что тип с плавающей запятой будет представлять доли minute, идущие от nanoseconds слева.

Если вам нужны режимы округления, отличные от "усечения до нуля", здесь приведены некоторые утилиты для Сделай так.

person Howard Hinnant    schedule 19.03.2015