using stringstream >> operator in if statement - c++

The following code snippet is meant to try and extract an integer from a string using a stringstream object and detect whether integer extraction was successful or not. The stringstream class inherits the >> operator to return a reference to an istream instance. How does failed integer extraction lead to myStream being equal to 0 while its str member is still strInput?
stringstream myStream(strInput);
if (myStream >> num){//successfull integer extraction}
else{//unsuccessfull integer extraction
cout<<myStream<<endl;
cout<<myStream.str().c_str()<<endl;}

There is an operator bool() or operator void*() for stream, which returns (something like) !fail() - or in case of void * a NULL when it failed. So, if the stream hasn't failed, it's fine. The operator >> returns a reference to the stream object, so the compiler says "Hmm, can't compare a stream object to truth, let's see if we can make a bool, or void * from it, yes we can, so let's use that.

The answer is in the operator that converts std::ios to void* (replaced with an operator to convert basic_ios to a bool in C++11):
A stream object derived from ios can be casted to a pointer. This pointer is a null pointer if either one of the error flags (failbit or badbit) is set, otherwise it is a non-zero pointer.
This operator gets called when your stream is used in an if, while, or for condition. There is also a unary ! operator for the cases when you need to write
if (!(myStream >> num)) {
...
}

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

Using stringstream and stream operator (>>) to put buffer data into specific data types?

As the title says, I'm doing input validation in C++ (in this case, for an int). I'm using a stringstream object to getline from the user, using the stringstream to assign to a variable with the stream operator, like so:
if (sStream >> validInteger) {
if ((sStream >> input)) {
code code code
}
}
So in the first if statement, I'm getting the stringstream object I've created, and putting it into an integer type. If I use the stringstream to put a char into that integer type, the statement will return false and it won't actually assign to the integer, as expected in this situation.
I know that if you try to assign a char literal to an int with the assignment operator, it will just cast to the ASCII int value for that char (like int charInt = 'c' works fine and assigns the ASCII value)
So this means there is logic built into the sStream >> validInteger statement to not cast the data type, and to return false and to not actually assign the data to that variable.
My question is in regards to the logic for this statement. Where is this logic built in? Is the logic to return false and not assign within the stream operator (>>) or the stringstream object?
I've tested this with iostream and fstream objects like cin and ifstream, and they perform the same way. But is this logic built into cin and fstream as well? Or is it just in the stream operator (>>)?
My code is functional and everything works as expected, I just wanted to clarify how C++ operators/objects actually work in this case for my own knowledge.
To elaborate, you can always check cppreference. At the top of stringstream you can see the inheritance tree, and compare with other input streams to see the first shared ancestor. Then, look at it:
The istream::operator>> states
(1) arithmetic types
Extracts and parses characters sequentially from the stream to interpret them as the representation of a value of the proper type,
which is stored as the value of val.
Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to false). Then (if
good), it calls num_get::get (using the stream's selected locale) to
perform both the extraction and the parsing operations, adjusting the
stream's internal state flags accordingly. Finally, it destroys the
sentry object before returning.
so quite a bit under the hood. A proper type checking is implemented.
The operation:
sStream >> validInteger
returns the stream object, not true, false or some error. The state of the the stream object (or any other stream object types in the iostream library) can be converted to something that can be tested with an if(), or other conditional construct, via an operator overload of the void * conversion in earlier versions of C++, and a bool conversion in the latest versions.

evaluating statement cin==(expression)

What does the code below intended to do?
return cin==(cout<<(f(a)==f(b)?"YES":"NO"));
assume f() is a string returning function and a and b are strings as well and function's signature is
string f(string a)
Thanks in advance!
The answer is: it depends on what C++ standard you're compiling against. It boils down to the conversion functions in std::basic_ios
C++03
Here, we have operator void*() const, which:
Returns a null pointer if fail() returns true, otherwise returns a non-null pointer. This pointer is implicitly convertible to bool and may be used in boolean contexts.
Thus, in the expression:
cin==(cout<<(f(a)==f(b)?"YES":"NO"));
we would print either "YES" or "NO", and the result of the stream output would be cout still (in the form of a std::ostream&). When we do the equality check, both operands would be implicitly converted to void* and so the expression checks to see if both streams failed. This is a particularly obfusticated way of doing:
cout << (f(a) == f(b) ? "YES" : "NO");
return cin.fail() && cout.fail();
C++11
With C++11, the operator void*() const is replaced by explicit operator bool() const. The explicit is key, as it means that the conversion function can only be used explicitly (as in, via a direct cast) or in a boolean context, as in:
if (cin) { // calls cin.operator bool()
}
Equality is not a boolean context, so in the expression
cin == cout
that conversion function will not be invoked. As there is no operator== defined on std::basic_ios (or std::istream or std::ostream), the expression will simply not compile.

which operator overloading has been used for ifstream object to evalute to boolean

I am new to C++. recently I come across the following code
ifstream in("somefile");
if(in){
//read the file....
}
I am wondering which operator overloading the ifstream might have used for the in object to automatically evaluate to boolean in if condition. I tried but couldnt find a clue. please help me. thank in advance
It's actually operator void *.
It's overridden to return a non-zero pointer if the stream is valid, and a NULL pointer otherwise. The pointer it returns is meaningless and should not be dereferenced, it's only there to be evaluated in a boolean context.
The void pointer conversion operator is often used for this purpose. Something similar to
struct ifstream {
typedef void * voidptr;
operator voidptr() const;
};
std::ifstream gets its conversion to bool from it's base class std::ios (std::basic_ios<char>) which has conversion function declared:
explicit operator bool() const;
It returns !fail().
(In the previous version of the standard ISO/IEC 14882:2003, std::basic_ios had a conversion function operator void*() const but this version of the standard has now been withdrawn.)

stream output and implicit void* cast operator function invocation

a code like
cin>> grade;
where grade is a standard data type returns a reference to cin(istream object) which enables cascaded inputs....
but i read that if
cin >>grade;
is used as a condition say in a while statement...the stream's void* cast operator function is called implicitly...and it converts reference to istream object into a non-null or null pointer depending upon success or failure of last input operation...and null pointer converts to false and non-null to true...my questions are:
what is the void * cast operator function and how does it work here
how is non-null pointer converted to true and null to false
1.what is the void * cast operator function and how does it work here
It looks something like this:
operator void* () const {
return fail() ? 0 : this;
}
The question is: why isn’t an operator bool used here? The answer is: because that allows invalid conversions which may hide bugs. The above is an example of the safe bool idiom.
However, this implementation is actually obsolete. There exist better implementations of this idiom; the article explains them.
2.how is non-null pointer converted to true and null to false
This is just how C++ works: any non-null pointer is considered equivalent to true in a conditional. Now, why does C++ invoke the operator void* here in the first place?
Essentially, when C++ sees an object of an unexpected type, it tries to apply one implicit conversion that would make the object type valid in this context. The compiler therefore tries out all available implicit conversions and looks whether the resulting type would be acceptable in this context.
This is happening her: the compiler sees while (cin >> grade). It knows that basic_istream isn’t valid in the context of a while conditional. So it finds that there is an operator void*, and a void* is valid in this context so C++ applies this conversion.