为任何载体编写操作符<<的模板

MK.*_*MK. 4 c++ templates c++11

我正在尝试为任何可迭代容器编写模板运算符.得到一个奇怪的错误:

#include <iostream>

template <typename C>
std::ostream& operator<<(std::ostream& os, const C& c) {
  os << "[";
  for (const auto& v : c) {
    os << v << " ";
  }
  os << "]";
  return os;
}
Run Code Online (Sandbox Code Playgroud)

vec.cc:5:6:错误:使用重载运算符'<<'是不明确的(操作数类型'std :: ostream'(又名'basic_ostream')和'const char [2]')os <<"[ "; ~~ ^ ~~~

为什么这个错误?我如何实现我想要的目标?

Nat*_*ica 9

添加

template <typename C>
std::ostream& operator<<(std::ostream& os, const C& c) {
  os << "[";
  for (const auto& v : c) {
    os << v << " ";
  }
  os << "]";
  return os;
}
Run Code Online (Sandbox Code Playgroud)

与其他全球超载的冲突operator <<.

要解决此问题,我们可以将模板限制为任何向量而不是使用任何类型

template <typename C>
std::ostream& operator<<(std::ostream& os, const std::vector<C>& c) {
  os << "[";
  for (const auto& v : c) {
    os << v << " ";
  }
  os << "]";
  return os;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

在这一行:

os << "[";
Run Code Online (Sandbox Code Playgroud)

编译器找到两个有效的函数:STL 的函数和您的函数。

为了解决冲突,您需要在模板声明中更加具体:

template <typename C>
std::ostream& operator<<(std::ostream& os, const std::vector<C>& c) {
  ...
Run Code Online (Sandbox Code Playgroud)

一般来说,将其扩展到容器需要一些花招,std::enable_if<>这可能只会让您更加困惑。我建议您只为您想要支持的每种类型的容器添加一个重载。

编辑:此外, ostream << T对于您不拥有的类型,覆盖 , 通常是一个坏主意,因为它最终会导致冲突。