Print vector of vectors to ostream

c++, ostream, vector

Solution

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'

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).

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...

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.

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).

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();
}

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.

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.

Problem

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; } ``` 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>&&' ``` 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? Thanks in advance.

Original source

Related problems