std :: chrono :: duration缺少立即滴答计数操作背后的原因是什么?

rwo*_*ols 16 c++ c++11 c++-chrono

假设我们有

#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;
Run Code Online (Sandbox Code Playgroud)

我们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;
}
Run Code Online (Sandbox Code Playgroud)

禁止用户duration直接操作的原因是什么?

Pix*_*ist 23

这样做是为了强制您坚持使用强类型值而不是任意值.

Bjarne Stroustrup在"The C++ Programming Language"(第4版,35.2.1,第1011页)中有关于此行为的示例:


" 这个时期是一个单位系统,所以没有=+=取一个普通的价值.允许这就像允许在5一个长度以米为单位添加一个未知的SI单位.考虑:

duration<long long, milli> d1{7}; // 7 milliseconds
d1 += 5; // error
[...]
Run Code Online (Sandbox Code Playgroud)

5这意味着什么?5秒?5毫秒?[...]如果您知道自己的意思,请明确说明.例如:

d1 += duration<long long, milli>{5}; //OK: milliseconds"
Run Code Online (Sandbox Code Playgroud)


How*_*ant 13

理由是保持duration代表的时间单位的完整性.

您可以将其rep视为无单元.但是duration它有一个单位的时间.可以在秒数之间加/减秒数.但是,如果不使表达式模糊不清,并且违反单位的代数,就不能增加秒数和无单位数量.

话虽这么说,人们可以将一个时间单位乘以一个标量(无单位)数量,结果仍然是一个时间单位.该库仅表示第一次供电或零功率的时间单位.提升到零功率的时间单位是标量,由...表示rep.时间单位也可以具有2或更大的幂,以及负功率.但是这个库并不代表这样的单位.

添加两个数量时,单位必须相同.

当乘以或除以两个量时,形成新单位(例如km/hr).当相同单位的数量相乘时,会添加它们的指数(例如,sec*sec == sec ^ 2).当划分相同单位的数量时,减去它们的指数(例如,秒/秒==秒^ 0 = =标量).

std::chrono::duration库是物理量库的一致子集,它只处理时间单位,只处理指数等于0和1的那些时间单位.


bam*_*s53 8

days += d; // Error!
Run Code Online (Sandbox Code Playgroud)

这是因为变量days以86,400秒d为单位,变量是无单位的.在标准尺寸分析中没有定义将一个单位的数量添加到无单位标量的结果.

days *= d; // Why is this okay?
days %= d; // And this too?
Run Code Online (Sandbox Code Playgroud)

因为无单位标量的乘法和除法数量并非毫无意义.将2秒乘以2导致4秒.

考虑将2秒乘以3秒; 结果是数量为6,单位为"秒平方".当然chrono::duration不是一个完整的单元库,所以你不能有像时间平方的单位,但像boost.units这样的库会支持它.