重载运算符<<() 用于 stl 容器

Overloading operator<<() for stl containers

本文关键字:lt stl 容器 用于 重载 运算符      更新时间:2023-10-16

我正在尝试重载 stl 容器(例如vectorlistarray(的operator<<()(即机械臂运算符((即任何支持基于范围的 for 循环且其value_type也对operator<<()有重载的容器(。我写了以下模板函数

template <template <class...> class TT, class ...T>
ostream& operator<<(ostream& out, const TT<T...>& c)
{
out << "[ ";
for(auto x : c)
{
out << x << " ";
}
out << "]";
}

它适用于vectorlist。但是当我尝试调用它时它会出错array

int main()
{
vector<int> v{1, 2, 3};
list<double> ld = {1.2, 2.5, 3.3};
array<int, 3> aa = {1, 2, 3};
cout << v << endl;  // okay
cout << ld << endl; // okay
cout << aa << endl; // error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
// cout << aa << endl;
//         ^
}

为什么它对array不起作用? 是否有任何解决方法可以解决此问题?

我已经在互联网和 SO 中搜索过,以查找是否有办法为 stl 容器重载operator<<()。 我已经阅读了 c++ stl 容器重载<<运算符中的答案,但它没有回答我的问题。 在我看来,漂亮打印C++ STL 容器中的答案似乎很完美。

G++ 版本:g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

编译命令:g++ -std=c++11

看看template <class...> class TT.此参数用于模板,即接受任意数量类型参数的任何模板。

现在看看std::array<class T, std::size_t N>.此模板不接受类型作为第二个参数。它接受一个整数常数。

因此,它不能是您定义的模板函数的参数,并且模板参数推导因此而失败。

至于使其工作,最简单的方法是提供一个仅接受std::array的(模板化(重载。模板参数将是(推导的(数组参数。

template<typename T, std::size_t N>
ostream& operator<<(ostream& out, std::array<T, N> const& a)
{
out << "[ ";
for(auto x : a)
{
out << x << " ";
}
out << "]";
return out;
}

您的重载不适用于std::array,因为它与std::array使用的模板不匹配。 与所有其他标准容器不同,std::array模板参数列表中有一个非类型模板参数。 它被定义为

template<typename T, std::size_t N>
struct array;

这不适用于template <template <class...> class TT, class ...T>,因为它只使用类型,不允许非类型、std::size_t N部分。

如果添加此重载,它应该可以工作

template <class T, std::size_t N>
ostream& operator<<(ostream& out, std::array<T, N>& c)
{
out << "[ ";
for(auto x : c)
{
out << x << " ";
}
out << "]";
return out;
}

另请注意,您不会在过载中返回out。 这是未定义的行为,因为您告诉编译器您正在返回某些内容,但您没有这样做。