'Overloading output stream operator for vector<T>

What is a recommended way to overload the output stream operator? The following can not be done. It is expected that compilation will fail if the operator << is not defined for a type T.

template < class T >
inline std::ostream& operator << (std::ostream& os, const std::vector<T>& v) 
{
    os << "[";
    for (std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
    {
        os << " " << *ii;
    }
    os << " ]";
    return os;
}

EDIT: It does compile, the problem was unrelated and was in the namespace. Thanks for assistance.



Solution 1:[1]

This is what you want:

template < class T >
std::ostream& operator << (std::ostream& os, const std::vector<T>& v) 
{
    os << "[";
    for (typename std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
    {
        os << " " << *ii;
    }
    os << "]";
    return os;
}

You forgot the std:: on the first ostream

You put an extra space after [ in os << "[".

and you need typename before std::vector<T>::const_iterator

Solution 2:[2]

template<typename T>
std::ostream& operator<<(std::ostream& s, std::vector<T> t) { 
    s << "[";
    for (std::size_t i = 0; i < t.size(); i++) {
        s << t[i] << (i == t.size() - 1 ? "" : ",");
    }
    return s << "]" << std::endl;
}

Solution 3:[3]

this compile for me on visual studio 2003. surely youshould use the keyword typename before the const std::vector<T> and I don't think the inline keyword has sense, IMHO templates are really close to inlining.

#include <ostream>
#include <vector>
#include <iostream>

template < class T >
std::ostream& operator << (std::ostream& os, typename const std::vector<T>& v) 
{
    os << "[ ";
    for (typename std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
    {
        os << " " << *ii;
    }
    os << "]";
    return os;
}

void Test()
{
    std::vector<int> vect;
    vect.push_back(5);
    std::cerr << vect;
}

Edit: I have added a typename also before the std::vector<T>::const_iterator as Nim suggested

Solution 4:[4]

For people coming into this thread after C++11, use the ranged for loop to make the code easier to read.

template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
  for (const auto &x : v) {
    os << '[' << x << ']';
  }
  return os;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Grimeh
Solution 3
Solution 4 Rase