std :: vector和std :: list的重载运算符

D C*_* dQ 6 c++ templates list vector operator-overloading

我想operator<<为两者重载std::liststd::vector使用以下代码.但这两个功能几乎相同.有没有办法将它们组合起来,创建一个更通用的重载?

#include <iterator>
#include <iostream>
#include <vector>
#include <list>

template <typename T>
std::ostream &operator<<(std::ostream &out, const std::vector<T> &v)
{
  if (!v.empty())
    std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
  return out;
}

template <typename T>
std::ostream &operator<<(std::ostream &out, const std::list<T> &v)
{
  if (!v.empty())
    std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
  return out;
}

int main()
{
  std::cout << std::vector<int>({1, 2, 3, 4}) << std::endl;
  std::cout << std::list<int>({1, 2, 3, 4}) << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*phe 4

您可以将模板与模板参数一起使用,如下例所示:

template <typename T, typename A, template <typename X, typename Y> class C> 
std::ostream &operator<<(std::ostream &os, const C<T,A> &container)
{
  if(!container.empty())
    std::copy(container.begin(), container.end(), std::ostream_iterator<T>(os, " "));
  return os;
}

int main() {
    list<int> l{1,2,3,4,5}; 
    vector<string> v{"one","two","three"};
    cout<<l<<endl<<v; 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在线演示

顺便说一句,您可能会在此 SO中找到使用模板的模板的其他示例

但你必须小心这种构造:

  • 它仅适用于使用两个模板参数定义的容器(因此适用于列表和向量;但不适用于集合或映射)。
  • 它可能与使用两个参数的其他模板类型发生冲突,而提取器没有专门化。

备注:如果您正在寻找通用解决方案,您最好考虑创建一个使用迭代器作为参数的适配器模板,然后为该适配器编写通用提取器。