Understanding behavior of cout.operator<<() - c++

According to the top answer to this question, cout << expr is equivalent to cout.operator<<(expr).
According to responses to this question, the statement above is untrue.
According to my own testing, cout.operator<<() is the same as cout << when given an integer. When given a float, cout.operator<<() coerces it to an integer. When given a string literal, as in cout.operator<<("hello world"), it outputs what appears to be a memory address. And when given a variable holding a std::string, it gives a compiler error.
Could anyone give a beginner-to-intermediate-level explanation of what's going on?

It depends on expr.
The answers to both questions are speaking to that specific case, not a blanket guarantee.
In fact, some of the operator<<s are free functions, and some are member functions.
Consult your favourite C++ reference to find out which.

The equivalency of cout << expr and cout.operator<<(expr) depends on what expr is.
If it lands up being a "built in" type, that cout "knows" about, then yes, it is equivalent to cout.operator<<(expr) (a member function).
If it is a "user type" (and std::string counts here), then it is an overloaded non-member method with a signature akin to std::ostream& operator<<(std::ostream&, const std::string&); etc.
Why does cout.operator<<("hello world") print a memory address?
The best member method overload to the above (since it is being forced to use the member method, is ostream& operator<<(const void* value); which outputs the value of the pointer (not what is being pointed to).
By contrast, cout << "hello world" calls the non-member overload ostream& operator<<(ostream&, const char*) and this in-turn inserts each character into the output.

Related

If you have two consecutive cout statements, and end the first with << and no semi-colon, it still compiles on Mac. Why? [duplicate]

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

what's the data type of a string inside the double quote in c++

void main() {
cout << "Hello World" << endl;
}
I'm not allowed to make any change to the above main function while the output on the screen need to be sth like:
initialize
Hello World
clean up
My thought is that I need to use overloading operator of << . However I need to know what's the data type of the double quoted string following the operator << , otherwise I will not make full use of my redefined << operator. Anyone any thought?
The type of the literal is "array of {suitable number of} const chars", but a better approach might be to have some kind of global object.
(Adding an overload for the array would probably not even work, because the existing overload for char const * would be getting in the way.)
You could redefine std::ostream& operator<< (std::ostream&, const char*). There's one huge problem with this approach: It is undefined behavior. The standard library already defines that function, and you are not allowed to redefine standard library functions.
The key to solving this problem is to recognize that cout is in the global namespace. The solution is simple: Write your own class that overloads operator<< and make a global variable named cout that is an instance of this class. That way you are not running into undefined behavior.
You'll also need to do something with that endl that is in the global namespace.
Your code should look something like
// Insert your code here.
int main () {
cout << "Hello World" << endl;
}
Since this looks like homework, I'll leave the rest up to you.
The type of a string literal is char const[n] where n is the number of characters in the string literal, including the terminating null character. Note, however, that the solution to your problem isn't overloading operator<<(). Instead, you should look at constructors, destructors, and variable with static live-time.

Why we don't use format specifiers with cout?

When we use printf then we use format specifiers (such as %c,%p) but when we use cout we don't use them why and what is being done in background because which we are not using them ?
I know they are used in differently in c and c++ but still i want to know how formatting is being done in cout, while it is done in printf through format specifiers.
In C++ the ostream::operator<< is overloaded for different types. You can try and dig through your standard library implementation to see exactly what it looks like, but it will boil down to something that is approximately equivalent to the following:
class ostream
{
public:
ostream& operator<<( int val );
ostream& operator<<( float val );
ostream& operator<<( const char* val );
};
A real implementation will be much more complicated than the above, but that is roughly the idea. The hope was that this implementation would be more efficient than printf because the compiler could more easily inline code when appropriate. Consider the following:
int val = 0;
printf("%d\n", val);
std::cout << val << std::endl;
In the case of the printf a naively compiled program (one compiled by a compiler with no knowledge of format specifiers) would have to do the parsing of "%d\n" at runtime. Contrast that with the std::cout call, in which case the compiler merely needs to figure out which overload to use, and can then inline the code.
That said, there is nothing in the c standard that says a compiler can't parse the format specifiers at compile time if they are available. In practice the performance difference between a c style logging library using format specifiers and c++ ostreams is... nuanced.
Because printf is properly designed and cout has nasty internal state. With printf, the way you want each argument formatted is explicit in the format string; there is no hidden state. With cout, you can also control formatting (things like field width, etc.), but it's a hidden state inside the iostream object. If the previous user of the stream has left it in a non-default state, you'll do the wrong thing unless you explicitly reset the state. You don't even want to think about what happens in multi-threaded usage cases...
Basically the answer is operator overloading. Functions can have the same name as long as they take different parameters. operator<< is the function name you're wondering about. The compiler knows the type of what you're trying to print out, and calls the correct operator<<.
This is why if you create your own object you can't just write std::cout << yourObject; and expect it to work how you'd probably like it to. You have to specify how it should be printed,
ostream& operator<<(ostream& os, const YourObject& rhs) {
os << rhs.member;
return os;
}
But, happily, that's already been done for you behind the scenes in the case of something like an int. See: http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2 for a full list of provided overloads.

Why does explicitly calling operator<< on std::cout cause unexpected output?

I was simply curious about what would happen if I called operator<< on std::cout explicitly because I learnt that a.operator() is exactly the same as a(). So I do it and it prints something weird:
#include <iostream>
using std::cout;
int main()
{
cout.operator<<("Hello World");
}
Output: 0x80486a0
Oddly, it outputs an address (the address may be different for you but it should still be an address). I'm thinking this is the address of the string so I try dereferencing it to get it to output the string:
*( cout.operator<<("Hello World") );
But I get a very long error
no match for operator* in '*std::cout.std::basic_ostream<...
I think this is pretty weird. Nothing of the std::cout definition would lead me to believe this would cause any different behavior; also given the fact that explicitly calling the operator function makes no difference (or should at least).
So why am I getting this output? Why am I receiving an address instead of the string itself when calling the operator explicitly? Is this even the address in memory or just garbage output? Any responses are appreciated.
The output operator for built-in strings, i.e., the on taking a char const* as argument, isn't a member of std::ostream. The operator taking a char const* is a non-member function would be called as
operator<< (std::cout, "Hello World");
There is, however, a member taking a void const* which formats the value of the pointer using hex notation. This member is the best match when passing any pointer explicitly to a member operator<< () of std::ostream.
Dereferencing the results of a the operator<<() doesn't work: The operators return a std::ostream& which doesn't have a unary operator*() overloaded. If you meant to dereference the argument, you'd call it like so:
std:cout.operator<< (*"Hello World");
However, this would just derference the char const* the string literal decays to, yielding an individual character H. The character output function isn't a member function, either, while the output operators for integers are, i.e., it would print character value of H. For a system using ASCII it would be 72.
I think the issue here is that the operator << that prints a C-style string to an output stream is actually a free function, not a member function of basic_ostream. However, basic_ostream does have an operator<< function that takes in a void* and prints out its address. As a result, if you explicitly try calling operator<< as a member function, you're calling the version that prints out an address of the C-style string, rather than the free function that prints out the characters a string.
You can see this by calling
operator<< (std::cout, "Hello, world!");
Which actually does print the string.
Hope this helps!

Runtime behavior with "C++ most vexing parse"

While trying to answer this question I found without () (which invokes "C++ most vexing parse") the output of g++ is 1 (Can be seen here: http://ideone.com/GPBHy), where as visual studio gives a linker error. I couldn't understand how the output can 1, any clues?
As the answers to the question already explain, due to the "Most Vexing Parse" the statement instead of defining an object named str with the two istream_iterators to specify its initializers, is parsed as a declaration of a function named str that returns a string.
So a simple version of the program resolves to, this online sample:
#include<iostream>
void doSomething()
{
}
void (*ptr)()=&doSomething;
int main()
{
std::cout << ptr << "\n";
std::cout << doSomething;
return 0;
}
Output:
1
1
Note that there is no overloaded operator << that takes an std::ostream and a function pointer as arguments, this is because there can be any number of user defined function types and ofcourse a standard overloaded api cannot account for them all.
Given that the compiler tries to find the best match among the existing overloads which happens to be bool (a function pointer is implicitly convertible to bool[#1]).
In particular,
basic_ostream& operator<< (bool& val );
Since the function pointer points to something and not null, the value is printed as 1.
[#1]C++03 4.12 Boolean conversions
1 An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool.