4

I just want to print the two values of my structure, but can't compile my code - I get: no operator “<<” matches these operands.

#include <iostream>

using namespace std;

struct SCoor
{
    int i, j;

    bool operator == (const SCoor & tmp) const
    {
        return (i == tmp.i && j == tmp.j);
    }

    bool operator < (const SCoor & tmp) const
    {
        return (i < tmp.i || (i == tmp.i && j < tmp.j));
    }

    ostream& operator << (ostream &o) {
        return o << i << " " << j;
    }

};


int main()
{

        SCoor tmp = { 3, 3 };

    cout << tmp;

    return 0;
}

How do I have to overload the operator "<<"?

Dru01
  • 95
  • 7

1 Answers1

8

You overload the << operator as a member function if you want your structure to be on the left hand side of the expression. So:

struct SCoor
{
    // ...

    SCoor& operator << (Stuff const& s) {
        // ...
        return *this;
    }

};

// ...

Stuff stuff;
SCoor scoor;

scoor << s; // insert s into my SCoor

If you want to make your struct the right hand side of the << expression you have to define a standalone function:

std::ostream& operator<<(std::ostream& os, SCoor const& scoor)
{
    return os << scoor.i << " " << scoor.j;
}

However it is quite common to make the external function a friend function and to define it in the struct definition:

struct SCoor
{
    // ...

    friend std::ostream& operator<<(std::ostream& os, SCoor const& scoor)
    {
        return os << scoor.i << " " << scoor.j;
    }

};

// ...

SCoor scoor;

std::cout << scoor << '\n';

But it is not a member of your struct, it is just defined inside its definition for convenience.

Justin
  • 24,288
  • 12
  • 92
  • 142
Galik
  • 47,303
  • 4
  • 80
  • 117
  • What's the difference between having it as friend inside the struct and having it just following the struct? Is that just to define the operator in a .h file without getting duplicate symbols? (i.e. an alternative to static inline) – Goswin von Brederlow Jun 14 '18 at 07:57
  • @GoswinvonBrederlow It also makes it simpler to define your function within a namespace so that it will be accessible outside the namespace and to objects within other namespaces. I (still) don't fully understand the name lookup rules but putting the friend function inside the class definition seems to make most problems go away. https://en.cppreference.com/w/cpp/language/adl – Galik Jun 14 '18 at 08:21
  • @GoswinvonBrederlow adding it as a friend also allows it to access `private` members, as if it were a member (which it would be, but for the language rule about parameter order) – Caleth Jun 14 '18 at 08:29
  • @Caleth But in a struct all members default to public. For classes I usually have my operator<< call class.print(out) instead of making it a friend. Galik: The namespace issue could be very useful. Have to test and read up on the rules there. – Goswin von Brederlow Jun 14 '18 at 10:22