将向量的向量打印到ostream [英] Print vector of vectors to ostream

查看:60
本文介绍了将向量的向量打印到ostream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码.我正在尝试将向量的向量输出到ostream.

Please consider the following code. I'm trying to output a vector of vectors to an 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/&没有-std = c ++ 11标志.在C ++ 11模式下,它在一半错误的页面中显示了这一行.

The statement where I output a vector of strings works. The one where I output a vector of vectors of strings doesn't. I'm using g++ 4.7.0. I've tried w/ & w/o the -std=c++11 flag. In C++11 mode, it gives me this line in the half-page of errors.

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>&&; .也许我不太了解.还有更好的方法吗?

I don't think I understand what it means. Could someone explain to me? I more or less know what an rvalue reference is, but I don't see why std::basic_ostream<char> wouldn't bind to std::basic_ostream<char>&&. Maybe I don't know it well enough. And is there a better way to do this?

谢谢.

推荐答案

您收到的错误有点误导.当我尝试编译您的程序时,我不得不对模板呕吐物进行相当多的研究,最终我想到了正在发生的事情:

The error you're getting is a bit misleading. When I tried to compile your program I had to dig into the template vomit quite a bit, and I ended up with what I thought was going on:

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名称空间中查找模板vector<>的重载(因为这是IT所在的位置).

Basically, when you called the copy algorithm, it used the output iterator, which used the << operator from within namespace std. Once there, lookup dictates that it try to find an overload for the template vector<> in the std namespace (because that's where IT resides).

因此,您需要做的是在名称空间std中为矢量模板声明流运算符.用 namespace std {} 包围代码,看看会发生什么...

So what you need to do is declare your stream operator for the vector template in namespace std. Surround your code with namespace std {} and see what happens...

应该注意,您所做的基本上是修改std :: vector<>并向其中添加以前没有的行为.这样做是非标准的,未定义的,并且很容易妨碍您.您可能会考虑其他选择.

It should be noted that what you're doing is basically modifying std::vector<> and adding behavior to it that wasn't there before. Doing this is non-standard, undefined, and can easily get in your way. You might consider other options.

我认为这是一个柯尼希(koenig)查找问题是错误的.并非如此,问题在于名称隐藏与类中发生的情况类似,在这里您声明基中某些内容的重载(而不是覆盖).

I was wrong about this being a koenig lookup thing. It's not, the issue is name hiding similar to what occurs in classes here you declare an overload of something in a base (not an override).

标准名称空间声明了几个'<<'运营商.这些基本上是名为 operator<< 的函数.从本质上讲,您所拥有的是:

The standard namespace declares several '<<' operators. These are basically functions named operator <<. In essence what you have is this:

void fun(int);

namespace Test {

  void fun() { fun(3); }

}

int main() {
    Test::fun();
}

请注意,您可以使用全局命名空间中的 fun(int)或其中没有任何名为 fun 的函数的任何命名空间.您不能在 Test 名称空间中使用它.

Note that you can use fun(int) from the global namespace or any namespace that does not have any function named fun in it. You can't use it from the Test namespace.

这就是为什么您使用运算符<<从全局名称空间中全局声明的全局变量可以很好地工作,但在 std 名称空间中则不能. std 命名空间已经具有与您要提供的重载相同的名称,因此对于 std 中的所有事物都隐藏了重载.如果您可以放置​​using声明,那么事情将会有所不同.

This is why your use of operator << declared globally works fine from the global namespace but not from within the std namespace. The std namespace already has things named the same thing as the overload you're trying to provide and so that overload is hidden from all things within std. If you could put a using declaration there things would be different.

这篇关于将向量的向量打印到ostream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆