What is the reason behind std::chrono::duration's lack of immediate tick count manipulation?

主宰稳场 提交于 2019-11-30 11:18:06

It is done to enforce you to stick to strongly typed values rather than arbitrary values.

Bjarne Stroustrup has examples regarding this behaviour in "The C++ Programming Language" (4th Ed., 35.2.1, pp. 1011):


"The period is a unit system, so there is no = or += taking a plain value. Allowing that would be like allowing the addition of 5 of an unknown SI unit to a length in meters. Consider:

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

What would 5 mean here? 5 seconds? 5 milliseconds? [...] If you know what you mean, be explicit about it. For example:

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

The rationale is to maintain the integrity of the unit of time which duration represents.

You can think of the rep as being unit-less. But the duration is has a unit of time. One can add and subtract seconds to/from seconds. But one can not add seconds and a unit-less quantity without making the expression ambiguous, and violating the algebra of units.

That being said, one can multiply and divide a unit of time by a scalar (a unit-less) quantity, and the result is still a unit of time. This library only represents units of time to the first power, or zero power. A unit of time raised to the zero power is a scalar and is represented by rep. Units of time can also have power of 2 or more, and negative powers. However this library does not represent such units.

When adding two quantities, the units must be the same.

When multiplying or dividing two quantities, a new unit is formed (e.g. km/hr). When quantities of the same units are multiplied, their exponents are added (e.g. sec * sec == sec^2). When quantities of the same units are divided, their exponents are subtracted (e.g. sec / sec == sec^0 == a scalar).

The std::chrono::duration library is a consistent subset of a physical quantities library that handles only units of time and only those units of time with exponents equal to 0 and 1.

days += d; // Error!

This is because the variable days is in units of 86,400 seconds and the variable d is unitless. The result of adding a quantity of one unit to a unitless scalar is not defined under standard dimensional analysis.

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

Because multiplying and dividing quantities by unitless scalars is not meaningless. Multiplying 2 seconds by 2 results in 4 seconds.

Consider multiplying 2 seconds by 3 seconds; the result is a quantity 6 with the unit 'seconds squared'. Of course chrono::duration isn't a complete units library so you can't have units like time squared, but libraries like boost.units will support that.

I would assume that this is done to force you to consider what the units of the duration you want to add/subtract are. It also keeps you from making any assumptions about what units the clock ticks are in.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!