I am curious if std::cout has a return value, because when I do this:
cout << cout << "";
some hexa code is printed. What's the meaning of this printed value?
Because the operands of cout << cout are user-defined types, the expression is effectively a function call. The compiler must find the best operator<< that matches the operands, which in this case are both of type std::ostream.
There are many candidate operator overloads from which to choose, but I'll just describe the one that ends up getting selected, following the usual overload resolution process.
std::ostream has a conversion operator that allows conversion to void*. This is used to enable testing the state of the stream as a boolean condition (i.e., it allows if (cout) to work).
The right-hand operand expression cout is implicitly converted to void const* using this conversion operator, then the operator<< overload that takes an ostream& and a void const* is called to write this pointer value.
Note that the actual value resulting from the ostream to void* conversion is unspecified. The specification only mandates that if the stream is in a bad state, a null pointer is returned, otherwise a non-null pointer is returned.
The operator<< overloads for stream insertion do have a return value: they return the stream that was provided as an operand. This is what allows chaining of insertion operations (and for input streams, extraction operations using >>).
cout does not have a return value. cout is an object of type ostream. operator << has a return value, it returns a reference to cout.
See http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/ for reference.
The only signature that matches is:
ostream& operator<< (ostream& ( *pf )(ostream&));
so it returns the pointer to the operator<< member.
the one in James' answer. :)
I believe that would be the address of the ostream object that "" got printed to
Related
What happens if I do not return din or dout, actually I'm reading a book in which writer returns back stream references
istream & operator>>(istream &din,vector &a)
{
for(int i=0;i<size;i++)
din>>a.v[i];
return din;
}
ostream & operator<<(ostream &dout,vector &a)
{
dout<<"("<<a.v[0];
for(int i=1;i<size;i++)
dout<<", "<<a.v[i];
dout<<")";
return dout;
}
The reason is a combination of several facts.
You want to be able to chain input and output operations as in
in >> x >> y;
out << z << std::precision(10) << t << std::endl;
so you must return something that allows operator<< again.
Since you want your operator to work on any istream, i.e. any object derived from std::istream, you cannot define
operator<<(istream_type, object); // take istream by value
since this would only work for the specific istream type istream_type, but not for a generic istream. For that one must use polymorphism, i.e. either take a reference or a pointer (which will be a reference or pointer to a class derived from std::istream).
Since you only have a reference to the istream, you cannot return the istream object itself (which may be of a type not even defined at the point of the definition of operator<<) but only the reference you've got.
One could get around this restriction by defining operator<< a template and take and return the istream_type by value, but that requires the istream type to have a copy constructor, which it may well not have for good reasons.
In order to envoke polymorphism one could, in principle, use pointers (to streams) rather than references. However, operator<<(stream*,const char*) is
not allowed in C++ (at least one operand must be of class or enumeration type).
Thus, with stream pointers one must use function-call syntax and you're back with C-style fprintf(stream*, args...).
Moreover, pointers can be null or dangling, which in fact is their default state (when declared without initializer), while a reference can be assumed to be valid (it cannot be declared without initializer).
In this case when the reference is returned you can combain the operator in a chain. For example
std::cout << "Hello " << "Rajat Verma";
This is equivalent to the following calls of the operator
operator <<( operator <<( std::cout, "Hello" ), "Rajat Verma" );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
returns reference to std::cout
One more thing is that ostream and istream standard objects such as cout and cin use a private copy constructors so they should be returned by reference not by value
When you type:
cout << vector;
cout has the type of ostream so when you use " << " it does need to return an arguement with ostream type for cout to work
I'm a C++ beginner, and I was told that in codes like
int a;
if(cin>>a);
if the input is successful, cin will yield true and vice versa.
But when I want to output the bool value,
cout<<boolalpha<<(cin>>a)<<endl;
it gives an address:
0x6fcc41e8
I was also told that cin is an object, but
cout<<&cin<<endl;
gives value
0x6fcc41e0
which is different by 8.
a. Why the first cout gives a address rather than a bool value?
b. Why two cout give different address?
Thanks.
cin >> a returns the stream object cin.
Until C++11, std::istream had a conversion function operator void*() const;, meaning that there was an implicit conversion from std::istream to void*. The actual value of the pointer was meaningless, except that a null value meant a failure had occurred and a non-null value meant success. This allowed things like if (cin >> a) to work correctly.
It appears you're using a pre-C++11 compiler or compiler settings, so that when you try to output it you get that meaningless void* value.
In C++11 and later, std::istream instead has a conversion function explicit bool() const;, meaning that there is a valid conversion from std::istream to bool, but only where explicitly requested. An if or while counts as explicitly requesting a conversion to bool, but
cout<<boolalpha<<(cin>>a)<<endl;
does not, so your code would not compile in C++11 and later. You would need
cout << boolalpha << static_cast<bool>(cin>>a) << endl;
instead.
First, observe that the result of cin >> a is a reference to an istream object.
Why the first cout gives a address rather than a bool value?
That is because an istream object must be "implictly convertible to bool" so that the expression can be used in the condition of an if statement. Before C++11, compilers typically allowed istream to be converted to void *. When you pass the result of cin >> a to cout via the << operator, it chooses this conversion to void * and prints whatever address is returned.
Why two cout give different address?
That is because the compiler chose to return some address that is not &cin when it converts to void *. (Remember that the precise value of the conversion to void * is irrelevant; it is only relevant whether the value is or is not NULL.)
boolalpha() returns an ios_base& not bool
use instead:
cout << (bool)(cin >> x) << endl;
What happens if I do not return din or dout, actually I'm reading a book in which writer returns back stream references
istream & operator>>(istream &din,vector &a)
{
for(int i=0;i<size;i++)
din>>a.v[i];
return din;
}
ostream & operator<<(ostream &dout,vector &a)
{
dout<<"("<<a.v[0];
for(int i=1;i<size;i++)
dout<<", "<<a.v[i];
dout<<")";
return dout;
}
The reason is a combination of several facts.
You want to be able to chain input and output operations as in
in >> x >> y;
out << z << std::precision(10) << t << std::endl;
so you must return something that allows operator<< again.
Since you want your operator to work on any istream, i.e. any object derived from std::istream, you cannot define
operator<<(istream_type, object); // take istream by value
since this would only work for the specific istream type istream_type, but not for a generic istream. For that one must use polymorphism, i.e. either take a reference or a pointer (which will be a reference or pointer to a class derived from std::istream).
Since you only have a reference to the istream, you cannot return the istream object itself (which may be of a type not even defined at the point of the definition of operator<<) but only the reference you've got.
One could get around this restriction by defining operator<< a template and take and return the istream_type by value, but that requires the istream type to have a copy constructor, which it may well not have for good reasons.
In order to envoke polymorphism one could, in principle, use pointers (to streams) rather than references. However, operator<<(stream*,const char*) is
not allowed in C++ (at least one operand must be of class or enumeration type).
Thus, with stream pointers one must use function-call syntax and you're back with C-style fprintf(stream*, args...).
Moreover, pointers can be null or dangling, which in fact is their default state (when declared without initializer), while a reference can be assumed to be valid (it cannot be declared without initializer).
In this case when the reference is returned you can combain the operator in a chain. For example
std::cout << "Hello " << "Rajat Verma";
This is equivalent to the following calls of the operator
operator <<( operator <<( std::cout, "Hello" ), "Rajat Verma" );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
returns reference to std::cout
One more thing is that ostream and istream standard objects such as cout and cin use a private copy constructors so they should be returned by reference not by value
When you type:
cout << vector;
cout has the type of ostream so when you use " << " it does need to return an arguement with ostream type for cout to work
I have simple lines of code, where I am using insertion operator << to show hello world string. If I use a operator b then it should result to a.operator(b); I try to do same thing with insertion operator and in output I got address of string, rather than actual string.
std::cout<<"Hello world"<<std::endl;
std::cout.operator<<("Hello world").operator<<(std::endl);
Output:
Hello world
0120CC74
I am using Visual Studio.
Does my operator conversion has any problem?
std::cout<<"Hello world"<<std::endl;
use overloaded output operator for const char*, that is free function, not member function.
std::cout.operator<<("Hello world").operator<<(std::endl);
use overloaded output operator for const void*, since const char* is implicitly convertible to const void*.
You can look at member overloads here and free overloads here
My bet is that member function operator for std::ostream(char*) is not overloaded.
If you look at ostream::operator<<, void* is best match and char* naturally gets converted to it, while global operator<<(std::basic_ostream), has exact overloads for char* types, which gets picked up.
Of course, they behave differently.
As the other answers say, the problem is that you are explicitly calling the member function operator <<, which is not overloaded for const char*.
To get the const char* overload, you need to call the free operator << function, which is appropriately overloaded:
operator<<(std::cout, "Hello World").operator<<(std::endl);
Similarly, there is no free function overload of operator << for writing an std::ostream& (*)(std::ostream&), so for std::endl you have to use the member function.
From this, we can see that you can not rewrite from the infix operator syntax (std::cout << ...) to function calling syntax (operator << (...)) without losing generality.
I'm trying to understand the underlying process in C++ that allows us to form the following expression in C++:
cout << "Hello," << "World" << a + b;
From my understanding, first, the insertion operator takes the ostream object cout and the string literal "Hello" as operands and the expression returns a type of cout and thus cout is now the type of the next string literal and finally also the type of the expression a + b.
I'm having trouble understanding the technical details of this process, I understand references are involved which allow us to do this ?
From my understanding, first, the insertion operator takes the ostream object cout and the string literal "Hello" as operands and the expression returns a type of cout...
Good so far...
and thus cout is now the type of the next string literal and finally also the type of the expression a + b.
I'm not sure what you're trying to say here. Maybe it'll help if the operators are grouped according to precedence:
(((cout << "Hello,") << "World") << (a + b));
The first time operator<< is called, its arguments are cout and "Hello", as you said. That returns cout. Then, the second time, the arguments are cout (the result of the previous one) and "World". Then, the third time, the arguments are cout and the result of a + b.
Maybe it will help further to rewrite the code using the (technically incorrect, see #DavidRodrÃguez-dribeas's comment) function call syntax:
operator<<(operator<<(operator<<(cout, "Hello,"), "World"), a + b);
Because each time operator<< is called it returns cout, the first argument of each call will be cout.
You can think of the << operator as being implemented something like this in terms of stdio functions (consider strings only for now):
ostream &operator <<(ostream &stream, const string &data)
{
fprintf(stream, "%s", data.c_str());
return stream;
}
This code doesn't work exactly as written because the first argument to fprintf should be a FILE*, not an ostream. But that's not important. The important part relevant to your question is the return stream; at the end, which returns the same stream you passed in back to the caller. With that, you can chain calls together.
The expression
cout << a << b;
is the same as
(cout << a) << b;
The result of (cout << a) is cout again (plus the side effect of actually printing the value of a).
The shift operators << group left to right. So statement
cout << "Hello," << "World" << a + b;
corresponds to expression
( ( ( cout << "Hello," ) << "World" ) << a + b );
In expression
cout << "Hello,"
there is used overloaded operator function << for left operand of type std::basic_ostream and right operand of type const char *
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
It returns reference to basic_ostream.
std::cout is defined as an object of type basic_iostream<char>
So after executing
cout << "Hello,"
you get reference to std::cout. which in turn becomes the left operand of expression
cout << "World"
and at last returned reference of the above expression becames the left operand of expression
cout << a + b
where a and b as I suppose are some arithmetic types. This expression is a call of overload operator function for std::basic_ostream and this arithmetic type.
As this operator returns refernce to std_basic_ostream or more precisely to std::cout it becames the return type of the full expression.