4
votes

I'm still quite new to the libraries and the documentation that I can find on std::chrono isn't working for me.

I'm trying to implement a container of objects that contain time stamps. The objects will all be stored in order from most recent to least recent and I've decided to try to use a std::chrono::time_point to represent each time stamp. The thread that processes the data will wake up periodically, process data, look at when it needs to wake up again and then sleep for that duration.

static std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds> _nextWakeupTime;

I'm under the impression that the declaration above utilizes a stead clock with millisecond precision.

The next step is to set the _nextWakeupTime to a representation of now;

_nextWakeupTime = time_point_cast<milliseconds>(steady_clock::now());

That line won't compile:

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::chrono::time_point<_Clock,_Duration>' (or there is no acceptable conversion)
        with
        [
            _Clock=std::chrono::system_clock,
            _Duration=std::chrono::milliseconds
        ]
        chrono(298): could be 'std::chrono::time_point<_Clock,_Duration> &std::chrono::time_point<_Clock,_Duration>::operator =(const std::chrono::time_point<_Clock,_Duration> &)'
        with
        [
            _Clock=std::chrono::steady_clock,
            _Duration=std::chrono::milliseconds
        ]
        while trying to match the argument list '(std::chrono::time_point<_Clock,_Duration>, std::chrono::time_point<_Clock,_Duration>)'
        with
        [
            _Clock=std::chrono::steady_clock,
            _Duration=std::chrono::milliseconds
        ]
        and
        [
            _Clock=std::chrono::system_clock,
            _Duration=std::chrono::milliseconds
        ]

I understand that on Windows systems, the stead_clock is the same thing as the system_clock, but what I don't know what's happening here. I know I could do this:

_nextWakeupTime += _nextWakeupTime.time_since_epoch();

I just don't feel like that's a good representation of what I should do.


Along the same lines, what is the best way to instantiate a time_point object of given clock/duration and set it equal to now?

1
std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds> => your impression is wrong. The precision of the clock is built in the clock, and you cannot change it. Here you merely requested that the time be expressed in milliseconds.Matthieu M.
@User - Your problem with the assignment is that different clocks can use a different epoch, so they might not agree on what now means. This is similar to "five minutes past midnight" not being the same in another time zone.Bo Persson

1 Answers

6
votes

The easiest thing for you to do is to give _nextWakeupTime type steady_clock::time_point.

steady_clock::time_point _nextWakeupTime;

You can query what the resolution of this time_point is with steady_clock::time_point::period, where that gives you a std::ratio with static members num and den.

typedef steady_clock::time_point::period resolution;
cout << "The resolution of steady_clock::time_point is " << resolution::num
     << '/' <<resolution::den << " of a second.\n";

It appears from your error messages that your vendor has made system_clock::time_point and steady_clock::time_point the same time_point and they thus share the same epoch and you can mix the two in arithmetic. To portably deal with this situation, you can query a time_point's clock with:

time_point::clock

I.e. in your implementation steady_clock::time_point::clock isn't steady_clock but system_clock. If you really want a time_point that is compatible with steady_clock::time_point but with millisecond resolution you could do this:

time_point<steady_clock::time_point::clock, milliseconds> _nextWakeupTime;