我希望能够做到以下几点:
std::cerr << std::chrono::system_clock::now() << std::endl;
并获得以下内容:
Wed May 1 11:11:12 2013
所以我写了以下内容:
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
}
哪个有效,但是从不同的命名空间调用它时我一直遇到问题。这应该只是在全局命名空间中吗?
答案 0 :(得分:4)
当你想确保调用正确的函数时,你应该在代码范围内放置一个using
声明来调用它。
例如:
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();
}
答案 1 :(得分:2)
一种方法可以将你的混乱放在你自己的namespace
中,并避免在你拥有的两种类型上重载操作符有点不礼貌的事情,那就是让你的输出语法稍微冗长:
std::cerr << pretty_print::format(std::system_clock::now()) << std::endl;
如下:
namespace pretty_print {
template<typename T>
struct print_wrapper { // boost::noopy optional -- if so, use it with && as an argument
T const& data;
print_wrapper( T const& t ): data(t) {}
};
template<typename T>
print_wrapper<T> format( T const& t ) {
return {t};
}
template<typename Clock, typename Duration>
std::ostream &operator<<(std::ostream &stream,
print_wrapper<std::chrono::time_point<Clock, Duration>>&& time_point)
{
// ...
}
}
并访问time_point.data
以获取<<
重载内的原始数据。
当您使用<<
包装类型时,print_wrapper<>
运算符将通过ADL(参数相关查找)找到,即使不将其拉入您使用它的namespace
!要使用此功能,您可以使用pretty_print::format(blah)
,也可以using pretty_print::format
将format
拉入当前范围。
实际上,您已标记了类型T
,以便在您自己的自定义重载集中使用。我喜欢这种“薄型包装”技术,因为它让我想起了std::move
。
这也可以让你说“我讨厌格式化double
的方式”,然后介绍一个<<
,它可以更好地格式化print_wrapper<double>
。
作为附带好处,您可以专门/过载print_wrapper
和format
来获取格式参数 - 因此您可以pretty_print::format( std::system_clock::now(), pretty_print::eDate::YMD )
或pretty_print::eFmt::compact
。