3

我希望能够做到以下几点:

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
}

哪个有效,但是从不同的名称空间调用它时我一直遇到问题。这应该只是在全局名称空间中是否正确?

4

2 回答 2

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();
}
于 2013-05-22T13:06:41.013 回答
3

一种让您自己保持混乱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中的原始数据。<<

<<当您使用包装类型时,将通过 ADL(依赖于参数的查找)找到该运算符print_wrapper<>,即使没有将其拉到namespace您使用它的位置!要使用它,您可以使用pretty_print::format(blah)using pretty_print::formatformat入当前范围。

实际上,您已将类型标记T为在您自己的自定义重载集中使用。我喜欢这种“瘦类型包装器”技术,因为它让我想起了std::move.

这也可以让您说“我讨厌doubles 的格式”,并介绍一个<<可以更好地格式化它们的print_wrapper<double>.

作为附带的好处,您可以专门化/重载print_wrapperformat采用格式化参数——这样您就可以pretty_print::format( std::system_clock::now(), pretty_print::eDate::YMD ), 或pretty_print::eFmt::compact.

于 2013-05-22T18:45:37.993 回答