WonderCsabo
WonderCsabo

Reputation: 12197

operator<< does not match

I have a code snippet like this:

class track {

public:

struct time {
    unsigned minutes, seconds;

    std::ostream& operator<<(std::ostream& o) {
        o << minutes << "minute(s) " << seconds << " second(s)";
        return o;
    }
};

...

std::ostream& operator<<(std::ostream& o) {
    o << "title: " << title << " performer: " << performer << " length: " << length << std::endl;
    return o;
}

private:
std::string performer, title;
time length;
};

However, if i compile this code, i got this error:

no match for 'operator<< ...'

Could you tell me what's wrong with this code?

Upvotes: 1

Views: 147

Answers (3)

piokuc
piokuc

Reputation: 26164

You want to have this operator outside of your class:

std::ostream& operator<<(std::ostream& o, const track &t) {
    return o << "title: " << t.title() << " performer: " << t.performer()
      << " length: " << t.length() << std::endl;
}

And, of course, you need to add appropriate getter functions to your class track, or, alternatively, make the operator a friend of the class track so it can access the track's private members directly.

Upvotes: 1

CygnusX1
CygnusX1

Reputation: 21769

If you want your object obj of class T to support typical streaming (e.g. cout << obj) you have to define an operator at global scope:

std::ostream& operator<<(std::ostream& o, const T& obj) {
  ...
}

(if the function needs to access private fields, you can declare it as a friend)

If, as in your code, you declare an operator as a member

std::ostream& T::operator<<(std::ostream& o)

you are esentially defining this:

std::ostream& operator<<(T& obj, std::ostream& o)

and you can use it like this: obj << cout, but that is probably not what you want!

Upvotes: 3

juanchopanza
juanchopanza

Reputation: 227370

You should declare the operators as a non-member functions:

std::ostream& operator<<(std::ostream& o, const track::time& t) {
    return o << t.minutes << "minute(s) " << t.seconds << " second(s)";
}

std::ostream& operator<<(std::ostream& o, const track& t) {
    return o << "title: " << t.title << " performer: " << t.performer << " length: " << t.length;
}

You would have to make the latter a friend in order to access the private data members.

Upvotes: 1

Related Questions