1

How to print the high_resolution_clock in C++?

#include <iostream>
#include <chrono>

typedef std::chrono::high_resolution_clock high_resolution_clock;

int main()
{
    std::cout << high_resolution_clock::now() << std::endl;
}

Building the above results in:

/home/greg/repositories/firstProject/main.cpp:27: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘std::chrono::_V2::system_clock::time_point {aka std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >}’)
     std::cout << high_resolution_clock::now() << std::endl;
     ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and

/home/greg/repositories/firstProject/main.cpp:27: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
     std::cout << high_resolution_clock::now() << std::endl;
                                             ^

After reading this answer I tried to iterate over the "container":

#include <iostream>
#include <chrono>

typedef std::chrono::high_resolution_clock high_resolution_clock;

int main()
{
    for(auto i: high_resolution_clock::now()){
        std::cout << i << std::endl;
    }
}

However this resulted in even more errors. I also tried using printf and casting high_resolution_clock::now() to a long long with no success.

Update:

Trying another answer suggested here also yielded more errors:

#include <iostream>
#include <chrono>

typedef std::chrono::high_resolution_clock high_resolution_clock;

int main()
{
    auto i = high_resolution_clock::now();
    std::cout << i.time_since_epoch() << std::endl;
}
Darthtrader
  • 238
  • 1
  • 8
  • Possible duplicate of [std::chrono and cout](https://stackoverflow.com/questions/7889136/stdchrono-and-cout) – user1810087 Sep 22 '17 at 10:27
  • @user1810087 I updated the post with the code which was suggested in the question you linked. The answer used a different library and the solution did not work in this example as it resulted in more compile errors. – Darthtrader Sep 22 '17 at 10:35

3 Answers3

8

I really appreciate the recommendation in Passer By's answer, however I'm afraid it isn't quite correct. My date library provides I/O for system_clock, but not high_resolution_clock. However Passer By's code happens to work with gcc because with that tool set high_resolution_clock is a type alias for system_clock.

I'm using clang, and with this toolset high_resolution_clock is a type alias for steady_clock (and ditto on Visual Studio). On these platforms Passer By's code will cause a compile-time error which complains that there is no operator<< found.

To understand why this is, it is important to understand the distinction between system_clock and steady_clock:

system_clock is like a watch (the thing on your wrist before smart phones took over the planet). It can tell you the time of day. And because no clock keeps perfect time, it sometimes asks another clock what time it is and makes tiny adjustments to itself to stay accurate.

steady_clock is like a stopwatch. It is great for timing a runner on a lap, or timing your function. It never adjusts itself, but strives to mark one second per second as best it can. But it has no idea what the time of day is, or even what day of the year.

high_resolution_clock also has no relationship to any human calendar or time system, and is allowed to be a typedef to either system_clock or steady_clock. And in practice, it always is a typedef to one of these clocks. Now that you know what system_clock and steady_clock are, just use one of those, and your code will be more portable.

My library provides I/O for system_clock, as its main purpose is to extend <chrono> into the realm of calendars.

You can use my library to stream out chrono::durations. So if you really wanted to, you can get the duration out of a high_resolution_clock and stream that:

#include <iostream>
#include <chrono>
#include "date.h"

typedef std::chrono::high_resolution_clock high_resolution_clock;

using date::operator<<;

int main()
{
    std::cout << high_resolution_clock::now().time_since_epoch() << std::endl;
}

This just output for me:

2553634286064557ns

On my platform this means my computer has been booted up for about that many nanoseconds. Or if you prefer something more readable:

    std::cout << date::format("%T\n", high_resolution_clock::now().time_since_epoch());

which just output:

709:32:51.552928058

My computer has been booted for about 709 hours and 32 minutes.

For a video tutorial of <chrono> which includes the distinction between system_clock and steady_clock, and a lot more, see:

https://www.youtube.com/watch?v=P32hvk8b13M

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • Thank you for the amazing answer, one question I have is when `system_clock` makes adjustments, does it ever "go back in time" or does it try to slow down instead it is ahead? That is, are sequential `system_clock`s strictly increasing in value? – Darthtrader Sep 22 '17 at 13:46
  • 3
    @GNettlefold: All of the `` clocks have a `static constexpr bool` value called `is_steady` which addresses your question. If `is_steady` is `true`, that means that the clock never goes backwards in time, and has a "close" approximation to a constant tick rate. For `system_clock`, the value of `is_steady` is unspecified. So if false on your platform, it might not be monotonic. `steady_clock::is_steady` is required to be true. – Howard Hinnant Sep 22 '17 at 14:59
2

Use Howard Hinnant's date library, which is being proposed for standardization.

#include <iostream>
#include <chrono>
#include "date.h"

typedef std::chrono::high_resolution_clock high_resolution_clock;

using date::operator<<;

int main()
{
    std::cout << high_resolution_clock::now() << std::endl;  // works!!
}

Live

Fun fact: Howard Hinnant is one of the authors of chrono and considers them not able to be outputted directly an oversight/defect

EDIT: Its not portable to output high_resolution_clock::time_point, check out Howard's answer for details

Passer By
  • 19,325
  • 6
  • 49
  • 96
  • Thank you for this. Do you mind briefly explaining how the above code works? (In case I encounter a similar type problem in the future) – Darthtrader Sep 22 '17 at 10:54
  • If I understand it correctly, `<<` is a function inside the "date.h" header file and you use that instead of the standard operator for the `high_resolution_clock` datatype? – Darthtrader Sep 22 '17 at 10:59
  • 1
    @GNettlefold `ostream` doesn't have an `operator<<` for the `chrono` stuff, `date.h` have them defined. To format them, `date.h` has very good support for them, check the link, there should be some tutorials. – Passer By Sep 22 '17 at 10:59
1

Not every thing can be directly used with cout.

Have a look at the example at this page on cplusplus.com

A simplified version as follows

// high_resolution_clock example
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>

int main()
{
    using namespace std::chrono;

    auto t1 = high_resolution_clock::now();

    //Do sth Here

    auto t2 = high_resolution_clock::now();

    duration<double> time_span = duration_cast<duration<double>>(t2 - t1);

    std::cout << "It took me " << time_span.count() << " seconds.";
    std::cout << std::endl;
    return 0;
}

I think this can solve your problem.

leyanpan
  • 433
  • 2
  • 9
  • From the page you link it says that the function `now()` "Returns the current time_point in the frame of the high_resolution_clock.". How can this time be printed without doing any computation on it first? – Darthtrader Sep 22 '17 at 10:40
  • You can then use the high_resolution_clock::now().time_since_epoch().count(), I think. (the time_point type has a member function called count) Sorry for the previous mistake – leyanpan Sep 22 '17 at 10:48
  • If the answer in my code works, you can simply change the t2 - t1 into t2 and it should still work. But the high_resolution_clock::now().time_since_epoch().count() works fine for my compiler. – leyanpan Sep 22 '17 at 11:12
  • Will accept now that you added `.time_since_epoch()` since it works :) – Darthtrader Sep 22 '17 at 11:44