SO Stinks
SO Stinks

Reputation: 3406

How to iterate over a vector data member from an overridden operator<<

This is my test program. The variable s1 contains a vector that contains objects of a user-defined type. I want to overload the << operator to print this vector nicely, one element per line.

#include <iostream>
#include "myclasses.h"
using namespace std;

int main() {

    myclass s1;

    s1.add_point(7000, 10);
    s1.add_point(8000, 11);
    s1.add_point(9000, 12);

    cout << s1 << endl;

    return 0;

}

Here's the class definition. Basically it's just an array of another user-defined objects. I want the << operator to print all entries, one per line. Assume that "anotherclass" has the needed support methods.

class myclass {
    vector<anotherclass> ps;
public:
    void add_point(double, double);
    friend ostream &operator<<( ostream &out, const myclass &s );
};

void myclass::add_point(double first, double second) {
    ps.push_back(anotherclass(first, second));
}

ostream &operator<<( ostream &out, const myclass &s ) {
    vector<anotherclass>::iterator itr;
    vector<anotherclass> psp=s.ps; // Why do I need this? Why can't I use s.ps.begin() and s.ps.end() in the for loop directly?
    for ( itr=psp.begin() ; itr != psp.end() ; ++itr ) {
        cout << "(" << itr->get_first() << "," << itr->get_second() << endl;
    }
    return out;
}

I have commented one line that I needed to add to get this to work in my program. I have no idea why that line is needed. Could somebody explain it to me?

Upvotes: 0

Views: 251

Answers (2)

Potatoswatter
Potatoswatter

Reputation: 137890

The iterator member type always allows you to modify the referenced object. Therefore you can't get an iterator from a const & argument such as s. You need to declare the local variable to have type vector< anotherclass >::const_iterator. Every container class has a const_iterator in parallel with iterator.

The reason your one-line fix works is that the newly-constructed vector is not const, unlike the function parameter it was constructed from.

In C++11, you can just use auto itr = s.ps.begin() and not ever name the iterator type. Or just use for ( auto const &obj : s.ps ) and forgo iterators completely.

Upvotes: 4

Pinch
Pinch

Reputation: 2888

My guess is because you declare s as const, so accessing to its iterator is not permitted. When you use vector psp=s.ps, your program essentially copy s.ps to a new vector psp which is modifiable.

Upvotes: 1

Related Questions