0

I have this following code which gives me error when compiling. The problem is happening at the point where I create a const_iterator inside the overloaded insertion operator (i.e) operator << () function. The template argument version of set is not correct I guess. Could anyone please pitch in and make this code working?

#include <iostream>
#include <set>

using namespace std;

class A {
public:
    int _i;
    A(int i) : _i(i) {}
    bool operator < (A a) const { return _i < a._i; }
};

class compA {
public:
    bool operator()(A a1, A a2) const { return (a1._i > a2._i); }
};

template<class T, class C>
std::ostream& operator << (std::ostream& os, const set<T, C>& s) {
    std::set<T, C>::const_iterator itr = s.begin();

    for (int i = 0; i < s.size(); i++) {
        os << *itr++ << " ";
    }

    return os;
}

int main() {
    set<A, less<A> > s1;
    set<A, compA> s2;

    s1.insert(A(9)); s1.insert(A(3)); s1.insert(A(-5)); s1.insert(A(3));
    s2.insert(A(2)); s2.insert(A(1)); s2.insert(A(7));

    cout << s1;
    cout << s2;
}
Ibrahim Quraish
  • 3,889
  • 2
  • 31
  • 39
  • possible duplicate of [GCC-4.7 Compilation error](http://stackoverflow.com/questions/10155571/gcc-4-7-compilation-error) – Nawaz Apr 16 '12 at 06:10
  • See the possible duplicate topic : you've not provided any implementation of `<` to compare two objects of type `A` . – Nawaz Apr 16 '12 at 06:11
  • @Nawaz he has. I think he just forgot to declare `operator <<(A)`. – Luchian Grigore Apr 16 '12 at 06:15
  • I got from some other forum, that I have to use the keyword 'typename' before the iterator declaration inside operator << () like typename std::set::const_iterator itr = s.begin(); Then the code will compile fine except it throws error at os << *itr – Ibrahim Quraish Apr 16 '12 at 08:56

2 Answers2

1

You forgot to declare and implement

std::ostream& operator << (std::ostream& os, const A& s)
{
    return os;
}

Also, the signature of the method in your comparison class should be:

bool operator()(const A& a1, const A& a2)
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Or as a (admittedly, usually inferior) alternative, something like `A::operator int`, that will allow the A to implicitly convert to something for which `operator<<` is already defined. – Jerry Coffin Apr 16 '12 at 06:16
0

*itr will be of type const A&, so when you do os<<*itr++ compiler doesn't know how to print the object A, you need to provide operator << for A also.

Naveen
  • 74,600
  • 47
  • 176
  • 233
  • so, if I provide a function inside class A as ostream& operator << (ostream& os) { os << this._i; } won't be there ambiguity between this and with the overloaded templated function? – Ibrahim Quraish Apr 16 '12 at 09:53