Calling a function which manipulates the ostream doesn't require parentheses. C++ - c++

I know a function cannot be called without a parentheses, however, let's say I have this piece of source code:
#include<iostream>
using namespace std;
ostream& test(ostream& os){
os.setf(ios_base::floatfield);
return os;
}
int main(){
cout<<endl<<scientific<<111.123456789;
cout<<endl<<test<<111.123456789;
}
/// Output:
/// 1.11235e+002
/// 111.123
There isn't any overloading for the left-shift operator, yet when I call the test(ostream& os) function in the cout at the main function, it does not require any parentheses. My question is why?

There isn't any overloading for the left-shift operator
Yes there is, it's defined in <ostream>.
It uses exactly the same technique that allows endl and scientific to work. There is an overload taking a function pointer, which calls the function pointer when it's written to a stream.
basic_ostream has these member functions which accept function pointers:
// 27.7.3.6 Formatted output:
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))
{ return pf(*this); }
basic_ostream<charT,traits>&
operator<<(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&))
{ return pf(*this); }
basic_ostream<charT,traits>&
operator<<(ios_base& (*pf)(ios_base&))
{ return pf(*this); }
cout << test uses the first of those overloads, which is equivalent to cout.operator<<(&test), which does return test(*this); so the call happens inside the overloaded operator<<.

ostream has overload of operator << for this case:
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
Calls func(*this);. These overloads are used to implement output I/O
manipulators such as std::endl.

Related

Overloading the stream insertion (<<) operator?

When we overload the stream insertion operator to work on user defined objects, we usually define it as a global friend function as follows:
ostream& operator << (ostream& out, const MyClass& x) {
// Do something
return out;
}
My question is, I believe the object cout (which is a global object) is passed as the first argument to this function. But, why? It's a global function, so it is accessible in this function anyway, why pass it as an argument. In other words, why not do the following:
ostream& operator << (const MyClass& x) {
// Do something
return cout;
}
There are two reasons.
One is semantic: the first argument need not be std::cout. It can be any std::ostream, be it std::cerr, a std::ofstream, a std::ostringstream, etc.
The second is syntactic: << necessarily takes two arguments, and there's no way to write an overload without two arguments (though the first argument can be a this argument).

Why does operator>> (or <<) overloading function need to receive an i\ostream reference?

From cplusplus.com, I saw that ostream class's member function operator<< looks like this:
ostream& operator<< (bool val); ostream& operator<< (int val);
.... and so on.
It does make sense because when you use the Cout object like cout<<x you activate the ostream& operator<< (int val) function, so you actually use the << operator on Cout object. This is very much like every other operator and sends the int variable to the function. What is the difference and what exactly happens when I want to stream an object of my own? Why does the syntax is suddenly ostream& operator<< (**ostream &os**, object ob)?
Why do I need to add the ostream var? I am still using cout<<ob so whay isnt it just ostream& operator<< (object obj)? All I pass is my object. The cout object is allready there.
operator<< is generally defined as a free function; that is, not a member function. Since it is an overloaded binary operator, that means it get's its left argument first and its right argument second.
The operator<< traditionally returns a reference to its left argument to enable the idiomatic chain of output.
To make it obvious to the reader, I tend to define my operator overloads using the lhs and rhs abbreviations; an operator<< would look similar to this, for some type T.
std::ostream& operator<<(std::ostream& lhs, T const& rhs)
{
// TODO: Do something
return lhs;
}
As a member function
As with other binary it could be defined as a member function. That is, let us suppose that you with defining your own iostream. Amongst other things, your class declaration may look like this. Again, T is a particular type.
class MyIOStream : public iostream
{
public:
MyIOStream& operator<<(T const& rhs);
}
In this case operator<< is a member function. It has the same semantics when used as <<.
References
Operators in C and C++ - a great summary of all the operators you can overload and their typical arguments.
why do I need to add the ostream var?
I'm sure it's there so that you can chain outputs together:
cout << foo << bar
The first call, cout << foo will result in an ostream reference that can be used for the << bar part.
Some of the stream extractors are members of basic_istream; because they are members, the basic_istream argument is implied. Some of the stream extractors are not members of basic_istream. Because they are not members, the basic_istream argument has to be part of the declaration.
Like this (oversimplified):
class basic_istream {
public:
basic_istream& operator>>(int& i);
}
basic_istream& operator>>(basic_istream&, std::string& str);
Both can be called in the same way:
int i;
std::cin >> i; // calls basic_istream::operator>>(int&)
std::string str;
std::cin >> str; // calls operator>>(basic_istrea&, std::string&)

"Essential C++": Providing Class Instances of the iostream Operators

From Essential C++: 4.10 Providing Class Instances of the iostream Operators
Often, we wish to both read and write objects of a class. For example,
to display our trian class object, we want to be able to write
cout << train << endl;
To support this, we must provide an overloaded instance of the output
operator:
ostream& operator<< (ostream &os, const Triangular &rhs)
{
os << "(" << rhs.beg_pos() << "," << rhs.length() << ")";
rhs.display(rhs.length(), rhs.beg_pos(), os);
return os;
}
We return the same ostream object passed into the function. This
allows multiple outptu operators to be concatenated. Both objects are
passed by reference. The ostream operand is not declared as const
because each output operation modifies the internal state of the
ostream object.
I'm kind of confused why the ostream operand cannot be declared as const.
If the output operator is declared as the following:
const ostream& operator<< (const ostream &os, const Triangular &rhs)
Is there any problem with the above declaration?
Thanks
The problem is that if the ostream argument (or conversely istream) was a constant reference, then the operator would not be able to modify the stream object. Insertion/extraction to the streams modify the stream state, so the existing operator<< are non-const operations. That in turn means that while you can declare and even define:
std::ostream const & operator<<( std::ostream const & s, Type const & t );
The problem is that the definition would not be able to actually write anything at all into the stream:
std::ostream const & operator<<( std::ostream const & s, Type const & t ) {
s << "Hi"; // Error: operator<<( std::ostream&, const char*) requires a
// non-const `std::ostream&`
return s; // This is fine
}
When outputting the variable rhs, some data members inside ostream& os such as output buffer or position of file write if os is a ofstream must be modified.
Declaring os as const forbids such a modification.
And, as shown here, if os is declared as const, then you cannot use it to output primitive data types since none of ostream::operator<<() is declared as constant member function.
Yes, the ostream argument os is modified by calling <<.

C++ manipulators?

How does the c++ standard define the recognition of manipulators or just manipulators in general?
For example:
using namespace std;
ostream& hello_manip(ostream& os){
os<<"Hello there, fine fellow!"; return os;
}
int main(){
cout<<hello_manip;
}
The code cout << hello_manip would seem to be translated into operator<<( cout, hello_manip ) or cout.operator<<(hello_manip), but instead it takes up the form of hello_manip( cout ).
There's an overload of operator<< that accepts a function pointer and invokes it. No magic involved.
Processing of simple manipulators such as yours is described in section 27.7.3.6.3 of the Standard.
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& (*pf) basic_ostream<charT,traits>&))
Effects: None. Does not behave as a formatted output function (as described in 27.7.3.6.1).
Returns: pf(*this).
basic_ostream<charT,traits>& operator<<(basic_ios<charT,traits>& (*pf) basic_ios<charT,traits>&))
Effects: Calls pf(*this). This inserter does not behave as a formatted output function (as described in 27.7.3.6.1).
Returns: *this.
basic_ostream<charT,traits>& operator<<(ios_base& (*pf)(ios_base&))
Effects: Calls pf(*this). This inserter does not behave as a formatted output function (as described in 27.7.3.6.1).
Returns: *this.
More complex manipulators (which accept parameters and carry state) are implemented by returning functor objects, which have their own operator<< overloads.

How cout distinguishes basic types?

Since my shifting from C to C++ I have a question on STL's formatting output. How ostreams tell one basic type from another?
In C with its printf and formatting strings it was pretty straightforward, but in C++ ostreams somehow distinguish basic types automatically. It puzzles me.
For example, in the following code,
int i;
float f;
std::cout << i << std::endl;
std::cout << f << std::endl;
how cout "knows" that i is an int and f is a float?
The compiler converts the operators to function calls. So that
std::cout << i
becomes
operator<<(std::cout, i)
Somewhere buried deep in the bowels of the standard library headers there are function declarations (functionally equivalent to):
std::ostream& operator<<(std::ostream& o, int i);
std::ostream& operator<<(std::ostream& o, double d);
That is, operator<< is overloaded. When the function call is made, the compiler chooses the function overload which is the best match to the arguments passed in.
In the case of std::cout << i, the int overload is chosen. In the case of std::cout<<d, the double overload is chosen.
You can see function overloading in action fairly simply with a contrived example:
#include <stdio.h>
void print(int i) {printf("%d\n", i);}
void print(double d) {printf("%f\n", d);}
int main()
{
int j=5;
double f=7.7;
print(j);
print(f);
}
Producing the output:
5
7.700000
Try it for yourself: http://ideone.com/grlZl.
Edit: As Jesse Good points out, the functions in question are member functions. So really we have:
std::cout << i
becomes
std::cout.operator<<(i)
And in the headers there are declarations (equivalent to):
class ostream {
ostream& operator<<(int i);
ostream& operator<<(double d);
...
};
The same basic idea holds, however.
There are operator<< overloads for each type (int, float etc).
The compiler will then choose the correct one at compile time.
In general, the operator<< have the form std::ostream& operator<<(std::ostream& stream, int number ), where the function is a global function defined in the std namespace. You can overwrite the definition of this function by declaring it in your own namespace (this is done via Argument Dependent Lookup).
The fact the function returns a reference to the stream, means you can string them together. Just remember, whenever you see operator<<, it really is just a function call.
If you want to have a look, and you're using VS, open
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\ostream.
There you'll find all the definitions if you're curious.
Overload resolution on the second argument to operator<<
Function overloading is a form of compile-time polymorphism. A simple example:
void times_two(int& x) { x *= 2; }
void times_two(double& x) { x *= 2; }
int i = 2;
double d = 2.5;
times_two(i); // i now 4
times_two(d); // d now 5.0
In the case of std::ostreams such as std::cout, the operator<<() functions overload in a similar way. From the Standard Library shipped with GCC 3.4.4:
__ostream_type&
operator<<(int __n);
__ostream_type&
operator<<(double __f);
It's an overloaded ostream operator <<. In c++ you can overload a function name based on it's parameters. This is basically what's happening here. http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/