5
votes

I think the following code can be used to create manipulators.

#include<iostream> 
ostream & symbol(ostream & output)
{
  return output << "\tRs";
}

it is working fine. The following statement

  cout << "Total amount: " << 567 << symbol; 

gives the output

 Total amount: 567   Rs

But I didn't understand why it is working. I have the following information about operator overloading in C++.

  1. only existing operators can be overloaded. New operators cannot be created. But the symbol is not existing operator.

  2. In the statement (cout << "Total amount: " << 567 << symbol;), it seems that << is the overloaded operator and symbol is a variable/object. But I didn't declare symbol as variable/object.

  3. why are they using the return statement (return output << "\tRs";)?. I think (return "\tRs";) or (output << "\tRs";) should work.( I tried but not working :) )

Actually I don't know how the above code is working. Is there anybody to explain the working of the above operator overloading?

3

3 Answers

7
votes

You are passing the function symbol to the operator <<. The << will call that function on the current ostream (with the ostream object as parameter), thus achieving the result you see. (The exact version of << called is: ostream::operator<< (ostream& ( *pf )(ostream&)); -- see the reference for more info)

The return type is ostream, to allow chaining of multiple <<'s. You would not need it technically in your particular case as << has access to the stream, but this is to keep it consistent with the operators (I think). Of course << requires this return parameter, so you have no choice :)

5
votes

std::ostream::operator<< is overloaded for function pointers of the type ostream &(*)(ostream &). The behaviour is simply to call the function on *this.

That's how things like std::hex work.

1
votes

There is an existing operator<< overload that is a member of basic_ostream

basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&));

The signature matches your function (as well as std::endl, std::flush, etc).