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?
One way to keep your mess in your own
namespace
, and avoid the somewhat impolite thing of overloading an operator on two types neither of which you own, would be to make your output syntax slightly more verbose:As follows:
and access
time_point.data
to get at the raw data within your<<
overload.The
<<
operator will be found via ADL (argument dependent lookup) when you use aprint_wrapper<>
wrapped type, even without pulling it into thenamespace
where you use it! To use this, you can either usepretty_print::format(blah)
or you couldusing pretty_print::format
to pullformat
into the current scope.In effect, you have flagged the type
T
for use in your own custom set of overloads. I like this technique of "thin typed wrappers" because it reminds me ofstd::move
.This also lets you say "I hate how
double
s are formatted", and introduce a<<
that formats them better that takes aprint_wrapper<double>
.As a side benefit, you can specialize/overload
print_wrapper
andformat
to take formatting arguments -- so you couldpretty_print::format( std::system_clock::now(), pretty_print::eDate::YMD )
, orpretty_print::eFmt::compact
.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: