将矢量的矢量打印到ostream
Print vector of vectors to ostream
请考虑以下代码。我正在尝试将向量向量输出到ostream。
#include <iterator>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
template<typename T>
std::ostream &operator <<(std::ostream &os, const std::vector<T> &v) {
using namespace std;
copy(v.begin(), v.end(), ostream_iterator<T>(os, "n"));
return os;
}
int main() {
using namespace std;
vector<string> v1;
cout << v1;
vector<vector<string> > v2;
cout << v2;
return 0;
}
我输出字符串向量的语句有效。我输出字符串向量向量的那个没有。我正在使用 g++ 4.7.0。我已经尝试过w/&w/o-std=c++11标志。在 C++11 模式下,它在半页错误中给了我这一行。
error: cannot bind 'std::ostream_iterator<std::vector<std::basic_string<char> >, char, std::char_traits<char> >::ostream_type {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
我想我不明白这意味着什么。有人可以向我解释一下吗?我或多或少知道什么是右值引用,但我不明白为什么std::basic_ostream<char>
不会绑定到std::basic_ostream<char>&&
.也许我不够了解它。有没有更好的方法可以做到这一点?
提前谢谢。
您遇到的错误有点误导。 当我尝试编译你的程序时,我不得不深入研究模板呕吐物,最终我得到了我认为发生的事情:
error: no match for 'operator<<' in '*((std::ostream_iterator<std::vector<std::basic_string<char> >, char, std::char_traits<char> >*)this)->std::ostream_iterator<std::vector<std::basic_string<char> >, char, std::char_traits<char> >::_M_stream << __value'
基本上,当您调用复制算法时,它使用输出迭代器,该迭代器使用命名空间 std 中的 <<运算符。 到达那里后,查找指示它尝试在 std 命名空间中查找模板向量的重载<>因为那是 IT 所在的位置(。
因此,您需要做的是在命名空间 std 中为矢量模板声明流运算符。 用namespace std {}
包围你的代码,看看会发生什么......
应该注意的是,你所做的基本上是修改std::vector<>并向其添加以前不存在的行为。 这样做是非标准的、未定义的,并且很容易妨碍您。 您可以考虑其他选择。
我错了,这是一个 koenig 查找的东西。 不是,问题是名称隐藏类似于类中发生的情况,在这里您声明了基中某些内容的重载(而不是覆盖(。
标准命名空间声明多个"<<"运算符。 这些基本上是名为 operator <<
的函数。 从本质上讲,您拥有的是:
void fun(int);
namespace Test {
void fun() { fun(3); }
}
int main() {
Test::fun();
}
请注意,可以使用全局命名空间中的fun(int)
,也可以使用其中没有任何名为 fun
的函数的命名空间。 不能从 Test
命名空间使用它。
这就是为什么全局声明运算符<<的使用在全局命名空间中工作正常,但在std
命名空间中则不能正常工作的原因。 std
命名空间已经具有与您尝试提供的重载命名相同的内容,因此重载对std
中的所有内容都是隐藏的。 如果你能在那里放一个使用声明,事情就会有所不同。
您需要此实用程序库:
- 漂亮的印刷C++ STL 容器
如果你想自己做这件事(以便自学(,那么你需要将两个重载定义为:
-
对于
std::vector<T>
:template<typename T> std::ostream &operator <<(std::ostream &os, const std::vector<T> &v) { using namespace std; copy(v.begin(), v.end(), ostream_iterator<T>(os, "n")); return os; }
-
对于
std::vector<std::vector<T>>
:template<typename T> std::ostream &operator <<(std::ostream &os, const std::vector<std::vector<T>> &v) { using namespace std; //NOTE: for some reason std::copy doesn't work here, so I use manual loop //copy(v.begin(), v.end(), ostream_iterator<std::vector<T>>(os, "n")); for(size_t i = 0 ; i < v.size(); ++i) os << v[i] << "n"; return os; }
如果您有这些重载,那么它们将一起递归处理这些情况:
std::vector<int> v;
std::vector<std::vector<int>> vv;
std::vector<std::vector<std::vector<int>>> vvv;
std::vector<std::vector<std::vector<std::vector<int>>>> vvvv;
std::cout << v << std::endl; //ok
std::cout << vv << std::endl; //ok
std::cout << vvv << std::endl; //ok
std::cout << vvvv << std::endl; //ok
- 如何循环打印顶点结构
- 为什么在popback()操作之后,它仍然打印完整的矢量
- oStream 不打印添加两个 valarray 的结果(使用运算符重载)
- 如何通过标准字符串打印 ostream 变量的值?
- 打印矩阵后分割错误,但在打印额外行后修复(ostream <<操作器)
- 无法使用Ostream打印,但可以使用COUT打印
- 使用 ostream 和运算符打印到控制台<<
- 超载Ostream运算符从文件打印矩阵
- Ostream打印内存映射,然后倾倒核心
- 打印任何带有非成员ostream重载函数的c++11数组
- 将矢量的矢量打印到ostream
- 使用std::ostream打印矢量
- 打印到std::ostream的时间
- 正在获取ostream模板以打印指针列表中的实例属性
- 用ostream打印到任何地方
- 为什么ostream为定义为' volatile char[] '的字符串打印' 1 ' ?
- 重载运算符 std::ostream& 运算符<<打印实例内存地址
- 使用ostream使用opengl在SDL中打印分数
- 为什么使用 ostream 运算符<<打印字符串时空格不充当分隔符?
- 自定义 ostream 仅打印"<<"链的最后一串