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?
The
iteratormember type always allows you to modify the referenced object. Therefore you can’t get aniteratorfrom aconst &argument such ass. You need to declare the local variable to have typevector< anotherclass >::const_iterator. Every container class has aconst_iteratorin parallel withiterator.The reason your one-line fix works is that the newly-constructed
vectoris notconst, 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 usefor ( auto const &obj : s.ps )and forgo iterators completely.