-1

Can someone explain the purpose of std::ostream &out for this friend overloaded operator function? Why not just use std::cout inside the function?

friend std::ostream& operator<<(std::ostream& out, const Complex& c) 
{
    out << c.real;
    out << "+i" << c.imag << endl;

    return out;
}

Instead, like so:

friend operator<<(const Complex& c) 
{ 
    std::cout << c.real;
    std::cout << "+i" << c.imag << endl;
}
Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
  • Do you understand the basics of operator overloading and friend functions? How much needs to be explained here? – scohe001 Feb 23 '21 at 18:16
  • As you tagged [tag:syntax], that is well explained [here](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading). – πάντα ῥεῖ Feb 23 '21 at 18:20
  • 3
    `operator<<` needs two arguments. It seems you are trying to write an overload for some form of unary shift operator, which does not exist. – François Andrieux Feb 23 '21 at 18:40

3 Answers3

9

Because this way you can use any ostream as output, not just std::cout for example, std::clog << c;

mitchnull
  • 6,161
  • 2
  • 31
  • 23
4

Displaying the output in a function and returning the output stream to the overloaded friend function have different meanings.

You can pass the initialized std::ostream& to any other ostream&. For example, std::cout, std::clog, std::cerr.

Note that this can be passed to the file stream instances such as std::ofstream when writing to a file.1

Also, in your second given example:

friend operator<<(const Complex &c)

You are missing a return type. The program will fail to compile. Also, two arguments are required to overload the operator<<.


1. Thanks to @Pete Becker for suggesting this important information.

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
  • Don't forget file streams. – Pete Becker Feb 23 '21 at 19:53
  • 1
    Yes, that's better. The key is that **any** kind of output stream can be passed to a stream inserter. The inserter doesn't care where the output is going; it just looks at the values of the object and puts appropriate text into the stream. That way you don't have to write different functions for different output media. None of that `printf`, `sprintf`, `fprintf` malarkey. +1. – Pete Becker Feb 24 '21 at 13:05
2

This:

friend std::ostream & operator << (std::ostream &out, const Complex &c) 
{ 
    out << c.real; 
    out << "+i" << c.imag << endl; 
    return out; 
}

is the function that gets called when you write:

Complex c;
std::cout << c;    // same as: operator<<( std::cout, c);

Calling std::cout << c; inside the implementation of operator<< would be bad, because then it would call itself recursively with no end.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185