Pretty printable nested vectors

I have the following code to print generic vectors correctly -:

// print a vector
template<typename T1>
std::ostream& operator <<( std::ostream& out, const std::vector<T1>& object )
{
    out << "[";
    if ( !object.empty() )
    {
        std::copy( object.begin(), --object.end(), std::ostream_iterator<T1>( out, ", " ) );
        out << *--object.end(); // print the last element separately to avoid the extra characters following it.
    }
    out << "]";
    return out;
}  

      

I get a compiler error if I try to print a nested vector.

int main()
{
    vector<vector<int> > a;
    vector<int> b;
    // cout << b ; // Works fine for this
    cout << a; // Compiler error
}  

      

I am using GCC 4.9.2 with a flag -std=c++14

.

The error message given by the compiler is - -

no match for 'operator<<' (operand types are
'std::ostream_iterator<std::vector<int>, char, std::char_traits<char>::ostream_type {aka std::basic_ostream<char>}' and 'const std::vector<int>')  

      

+3


source to share


2 answers


std::copy( object.begin(), --object.end(), std::ostream_iterator<T1>( out, ", " ) );

      

You are using copy for an ostream iterator that is not defined for a vector std::vector<>

. One job is to implement operator <<

in terms of operator <<

children.

if ( !object.empty() )
{
    //std::copy( object.begin(), --object.end(), std::ostream_iterator<T1>( out, ", " ) );
    for(typename std::vector<T1>::const_iterator t = object.begin(); t != object.end() - 1; ++t) {
        out << *t << ", ";
    }
    out << *--object.end(); // print the last element separately to avoid the extra characters following it.
}

      



Here's a live example

This method will not work for the same reason for std::vector<my_type>

if opeartor <<

not defined forclass my_type

+2


source


Just using regular forloop instead of std :: copy will solve this problem. As @Mohit suggested, the ostream iterator is undefined for nested vectors.

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;

// print a vector
template<typename T1>
std::ostream& operator <<( std::ostream& out, const std::vector<T1>& object )
{
    out << "[";
    if ( !object.empty() )
    {
        for(typename std::vector<T1>::const_iterator
            iter = object.begin();
            iter != --object.end();
            ++iter) {
                out << *iter << ", ";
        }
        out << *--object.end();
    }
    out << "]";
    return out;
}

int main() {
    std::vector<std::vector<int> > a;
    std::vector<int> b;
    b.push_back(1);
    b.push_back(2);
    std::vector<int> c;
    c.push_back(3);
    c.push_back(4);
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    a.push_back(b);
    a.push_back(c);
    cout << a; // Compiler error
    return 0;
}

      



The result will look like this:

[1, 2]
[3, 4]
[[1, 2], [3, 4]]

      

+2


source







All Articles