Search code examples
c++c++11operator-overloadingostream

C++11 Adding a stream output operator for std::chrono::time_point


I would like to be able to do the following:

std::cerr << std::chrono::system_clock::now() << std::endl;

And get the following:

Wed May  1 11:11:12 2013

So I wrote the following:

template<typename Clock, typename Duration>
std::ostream &operator<<(std::ostream &stream,
  const std::chrono::time_point<Clock, Duration> &time_point) {
  const time_t time = Clock::to_time_t(time_point);
#if __GNUC__ > 4 || \
    ((__GNUC__ == 4) && __GNUC_MINOR__ > 8 && __GNUC_REVISION__ > 1)
  // Maybe the put_time will be implemented later?
  struct tm tm;
  localtime_r(&time, &tm);
  return stream << std::put_time(tm, "%c");
#else
  char buffer[26];
  ctime_r(&time, buffer);
  buffer[24] = '\0';  // Removes the newline that is added
  return stream << buffer;
#endif
}

Which works, but I keep getting issues when calling this from different namespaces. Is it correct that this should just be in the global namespace?


Solution

  • When you want to be sure that the right function gets called, you should put put a using declaration in the scope of the code that will call it.

    For example:

    namespace pretty_time {
      /* your operator<< lives here */
    }
    
    
    void do_stuff() {
      using namespace pretty_time;   // One way to go is this line
      using pretty_time::operator<<; // alternative that is more specific (just use one of these two lines, but not both)
      std::cout << std::chrono::system_clock::now();
    }