微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 std::vector 的流运算符进行参数相关查找

如何解决使用 std::vector 的流运算符进行参数相关查找

我在我的命名空间中为 std::vector 创建了一个输出运算符,并且我能够在我以前的调试代码中使用它:

namespace my_company {

template <typename T>
std::ostream &operator<<(std::ostream &os,std::vector<T> const &vec) {
  os << "{";
  for (int i = 0; i < vec.size(); ++i) {
    if (i != 0) {
      os << ",";
    }
    os << vec[i];
  }
  os << "}";
  return os;
}

template <typename T>
void debug_impl(T const &var,char const *const expr,char const *const file,int const line) {
  using std::vector;
  std::lock_guard lg(debug_print_mutex);
  std::cout << "DEBUG " << file << ":" << line << " T" << std::this_thread::get_id() << "\n  " << expr << ": "
            << var << std::endl;}

#define DEBUG(var) ::my_company::debug_impl(var,#var,__FILE__,__LINE__)

}

但现在我想使用我的记录器类:

namespace my_company {

class Logger {
 public:
  virtual ~Logger() = default;

  virtual void log_impl(LogLevel log_level,std::string message) = 0;

  template <typename... T>
  void log_bits(LogLevel log_level,T const &...ts) {
    if (log_level >= threshold)
      log_impl(log_level,format_bits(ts...));
  }
  
  template <typename... T>
  void trace(T const &...ts) {
    log_bits(LogLevel::trace,ts...);
  }

 private:
  LogLevel threshold = LogLevel::trace;
};

}

格式函数是这样的:

namespace my_company {

template <typename... T>
std::string format_bits(T const &...ts) {
  std::ostringstream oss;
  // The following is a C++17 [fold expression](https://en.cppreference.com/w/cpp/language/fold).
  (oss << ... << ts);
  return oss.str();
}

}

debug_impl 函数中,我现在只是委托给记录器:

namespace my_company {

template <typename T>
void debug_impl(T const &var,int const line) {
  logger->template trace(file,":",line," T",std::this_thread::get_id(),"\n  ",expr,": ",var);
}

}

Clang 不喜欢那样:

logger.h:29:11: error: call to function 'operator<<' that is neither visible in the template deFinition nor found by argument-dependent lookup
  (oss << ... << ts);
          ^
logger.h:44:27: note: in instantiation of function template specialization 'my_company::format_bits<const char *,char [2],int,char [3],std::thread::id,char [4],const char *,std::vector<bool,std::allocator<bool>>>' requested here
      log_impl(log_level,format_bits(ts...));
                          ^
logger.h:69:5: note: in instantiation of function template specialization 'my_company::Logger::log_bits<const char *,std::allocator<bool>>>' requested here
    log_bits(LogLevel::trace,ts...);
    ^
util.h:693:20: note: in instantiation of function template specialization 'my_company::Logger::trace<const char *,std::allocator<bool>>>' requested here
  logger->template trace(file,var);
                   ^
rotating_buffer.h:40:5: note: in instantiation of function template specialization 'my_company::debug_impl<std::vector<bool,std::allocator<bool>>>' requested here
    DEBUG(used);
    ^
util.h:699:42: note: expanded from macro 'DEBUG'
#define DEBUG(var) ::my_company::debug_impl(var,__LINE__)
                                         ^
logger.h:13:15: note: 'operator<<' should be declared prior to the call site
std::ostream &operator<<(std::ostream &os,std::vector<T> const &vec) {
              ^

我已经声明,在调用站点之前,它都在 logger.h 文件中声明,该文件被其他文件包含。 operator<< 是该文件中的第一件事,因此它应该可用。我认为额外的模板层并没有让它变得更容易。

我已经阅读了一些其他问题,但我不明白如何解决这个问题,因为不允许将 operator<< 放入 std,但它在 { {1}} 并将其放入全局命名空间也不起作用。我能做什么?


我们在 Linux 上使用 Clang 11 和 C++20。


有点相关:

解决方法

这似乎是一个 clang 11 错误。

Clang 12 接受代码 Demo

作为变通方法,您可以使用,而不是 (oss << ... << ts);

((oss << ts),...);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。