Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: setting time using suffixes

Tell me, Can the following exist in C ++ 11/14/17:

1) set time using time suffixes

double time1 = 1s; // time1 = 1.0
double time2 = 2m; // time2 = 120.0
double time3 = 7ms; // time3 = 0.007 

2) get the string value of the time with the suffix as set

std::cout << getTime(time1); // cout 1s
std::cout << getTime(time2); // cout 2s
std::cout << getTime(time3); // cout 7ms
like image 945
Zhihar Avatar asked Oct 20 '25 04:10

Zhihar


2 Answers

  1. Yes, via std::chrono_literals.

  2. Not directly, but you can print the typeid (usable for debugging) or provide overloads for streaming durations yourself.

I have included explicit overloads of operator<< here, but as @JeJo, it can also be done with templates: https://wandbox.org/permlink/o495eXlv4rQ3z6yP

#include <iostream>
#include <chrono>
#include <typeinfo>

using namespace std::chrono_literals;

// example overloads for streaming out durations
std::ostream& operator<<(std::ostream& os, const std::chrono::nanoseconds& v) {
    return os << v.count() << "ns";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::microseconds& v) {
    return os << v.count() << "us";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::milliseconds& v) {
    return os << v.count() << "ms";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::seconds& v) {
    return os << v.count() << "s";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::minutes& v) {
    return os << v.count() << "min";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::hours& v) {
    return os << v.count() << "h";
}

int main() {
    auto time1 = 1s;
    auto time2 = 2min;
    auto time3 = 7ms;
    std::cout << time1.count() << " " << typeid(time1).name() << "\n";
    std::cout << time2.count() << " " << typeid(time2).name() << "\n";
    std::cout << time3.count() << " " << typeid(time3).name() << "\n";
    std::cout << time1 << "\n";
    std::cout << time2 << "\n";
    std::cout << time3 << "\n";
}

Possible output:

1 NSt6chrono8durationIlSt5ratioILl1ELl1EEEE
2 NSt6chrono8durationIlSt5ratioILl60ELl1EEEE
7 NSt6chrono8durationIlSt5ratioILl1ELl1000EEEE
1s
2min
7ms
like image 64
Ted Lyngmo Avatar answered Oct 22 '25 21:10

Ted Lyngmo


  1. Yes, as of C++14, you can use the user-defined literals described here to create durations:

    #include <chrono>
    using namespace std::literals;
    auto time1 = 1s; // std::chrono::seconds{1}
    auto time2 = 2min; // std::chrono::minutes{2}
    auto time3 = 7ms; // std::chrono::milliseconds{7}
    

    These create type-safe objects that store an integral value. You can use double internally fairly easily, but those specializations don't come with a pretty type alias out of the box:

    namespace chr = std::chrono;
    using dbl_seconds = chr::duration<double, chr::seconds::period>;
    // Likewise for other units
    dbl_seconds time1 = 1s;
    

    If you absolutely need the internal value (usually a bad idea), you can access it with .count().

  2. This is planned to come in C++20:

    std::cout << time1; // 1s, or 1.000000s if using double
    

    Until then, the best you can do with standard C++ is to suck it up and use count():

    std::cout << time1.count() << 's'; // 1s
    

For a good look into the library, watch Howard's CppCon talk. His other talks cover the planned C++20 additions.

like image 28
chris Avatar answered Oct 22 '25 20:10

chris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!