Yves
Yves

Reputation: 12371

Are all of zero() in chrono the same thing

I've found many zero() in the namespace std::chrono:

std::chrono::system_clock::duration::zero();
std::chrono::minutes::zero();
std::chrono::seconds::zero();
std::chrono::milliseconds::zero();
...

Are they all the same thing?

I'm coding with std::chrono and I have many variables whose types are std::chrono::seconds, std::chrono::milliseconds. If I want to check if a variable is zero or not, which one should I use?

std::chrono::seconds start = std::chrono::duration_cast<T>(std::chrono::system_clock::now().time_since_epoch()); // get current time
// something
std::chrono::seconds end = std::chrono::duration_cast<T>(std::chrono::system_clock::now().time_since_epoch()); // get current time
if (end - start == 0) // std::chrono::system_clock::duration::zero()? std::seconds::zero()? std::milliseconds::zero()?
{
    // something
}

In this if condition, which kind of zero should I use? Or I can use anyone because they are exactly the same? You may want to say end == start works too, I can live with that but I still want to know if all of these zeros are the same thing.

Upvotes: 1

Views: 795

Answers (1)

Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33854

So the seconds, milliseconds etc are typedefs of the duration type with different ratios:

...
std::chrono::milliseconds   duration</*signed integer type of at least 45 bits*/, std::milli>
std::chrono::seconds    duration</*signed integer type of at least 35 bits*/>
std::chrono::minutes    duration</*signed integer type of at least 29 bits*/, std::ratio<60>>
std::chrono::hours  duration</*signed integer type of at least 23 bits*/, std::ratio<3600>>
...

See here

So when you call the function zero on this type, it produces the value in the form of this type, but it calls the same function implementation (std::chrono::duration::zero) to do so. They are also all comparable and equivalent:

#include <chrono>
#include <ratio>
int main() {
    static_assert((std::chrono::hours::zero() == std::chrono::nanoseconds::zero()) &&
                  (std::chrono::duration<short, std::nano>::zero() ==
                   std::chrono::duration<int, std::deci>::zero()) &&
                  (std::chrono::duration<short, std::deca>::zero() ==
                   std::chrono::duration<long, std::exa>::zero()) &&
                  (std::chrono::duration<long, std::atto>::zero().count() ==
                   std::chrono::duration<float, std::exa>::zero().count()));
// This compiles.
}

Example from the function link above.

From there, which one to use is not something of function, but opinion. I would suggest that since you have chosen std::chrono::seconds as the type of start and end that you should use std::chrono::seconds::zero() to keep it consistent. But this is simply my opinion.

If you have access to chrono literals (c++14) then the suggestion from @HowardHinnant is even more concise:

using namespace std::chrono_literals; // Somewhere in your cpp
...
if (end - start == 0s) {   

Upvotes: 2

Related Questions