evaluating statement cin==(expression) - c++

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.

Related

`ofstream` compared to 0

I'm upgrading existing old code to use VS 2019*, in the code I have the following function that fails on the return line:
int foo(const char *fn) const
{
ofstream out(fn,ios::binary);
if (out)
{
//...
}
return out!=0;
}
The error I get is:
Error C2678 binary '!=': no operator found which takes a left-hand operand of type 'std::ofstream' (or there is no acceptable conversion)
What was the original poet's intention, and what is the best way to fix the issue?
*This code compiles successfully on VS 2010.
I suppose with the upgrading, you're switching to C++11 mode.
Before C++11, std::basic_ios (the base class of std::basic_ofstream) could convert to void* implicitly.
Returns a null pointer if fail() returns true, otherwise returns a non-null pointer.
Then out!=0 is checking whether the stream has no errors and is ready for further I/O operations.
Since C++11, there's only one conversion operator which could convert std::basic_ios to bool. Note that the operator is marked as explicit, so the implicit conversion isn't allowed for out!=0.
You can change the code to !!out (invoking operator!), or !out.fail(), or static_cast<bool>(out) (explicit conversion via operator bool).
There are two operators in the class std::basic_ios that can be applied in such a situation. They are
explicit operator bool() const;
bool operator!() const;
So you can for example either write
return bool( out );
or
return !!out;
or
return !out != true;

Is there a special function which can check nullptr of shared_ptr outside if sentence? [duplicate]

In C++, I can write something like:
shared_ptr<A> a_sp = someFunctionReturningSharedPtr();
if (a_sp) {
cout << a_sp->someData << endl;
} else {
cout << "Shared Pointer is NULL << endl;
}
Why does if (a_sp) check work correctly? a_sp is not a boolean, but how is it checked for true or false? How does the if condition know to check the result of a_sp.get() function? Or if it does not, how is the NULLity of the a_sp checked? Is there some function in shared_ptr defined that converts it to boolean value?
shared_ptr has an operator unspecified-bool-type() const that allows it to be used in boolean contexts. The unspecified-bool-type is typically defined as a pointer to function, or pointer to member-function, to disallow accidental matching to bool function overloads.
In C++0x the idiom is to use explicit operator bool() const;, which disallows implicit conversions (such as function calls, conversions to int for arithmetic, and so on), but still allows the shared_ptr to be converted to bool in boolean contexts.
shared_ptr has operator bool(), which returns true if it is not empty.
For example, this is Microsoft implementation of shared_ptr::operator bool(): http://msdn.microsoft.com/en-us/library/bb982901.aspx
shared_ptr::operator boolean-type - Tests if an owned resource exists.

How this cout will work?

I am checking one code and getting confused by this line.
if( cout > 0 )
{
//some statements
}
Please tell me if we can use cout like that. And how it will work?
cout is a variable of the type ostream (or some type derived thereof). The ostream has a conversion to void *(pre-C++11) or bool (C++11) - both of these conversion functions check for "error status" in the filestream, and return NULL or false respectively if there is an error). Both these will compare to zero as zero is the same as NULL and false respectively and thus the statement becomes (void *)cout > NULL or (bool) cout > false, which will be true if cout is not NULL or false (this means "has no error").
[Note: a pointer comparison with NULL may not work correctly when using p > NULL, since pointers may be "negative", in which case it isn't greater than NULL - I would prefer to see if (cout != 0) or if (!cout) as a safer/better choice].
std::cout inherits an explicit operator bool() (C++11) or operator void*() (pre-C++11) from std::basic_ios. Both of these have the ability to be compared with 0. However, each has a problem:
The operator void*() conversion will (thanks to James Kanze for pointing this out below) not be guaranteed to work as expected. The 0 will be converted to a void * as well, and then, since one is null and one is not, the comparison is unspecified (N3485 § 5.9/2).
The explicit operator bool() conversion will not be triggered in this context, causing that to not compile. However, I don't think there is any main library implementation that uses this over the operator void*() yet, even though they should. Clang might have this done for next release if it's C++11-complete.

How does shared_ptr work in if condition

In C++, I can write something like:
shared_ptr<A> a_sp = someFunctionReturningSharedPtr();
if (a_sp) {
cout << a_sp->someData << endl;
} else {
cout << "Shared Pointer is NULL << endl;
}
Why does if (a_sp) check work correctly? a_sp is not a boolean, but how is it checked for true or false? How does the if condition know to check the result of a_sp.get() function? Or if it does not, how is the NULLity of the a_sp checked? Is there some function in shared_ptr defined that converts it to boolean value?
shared_ptr has an operator unspecified-bool-type() const that allows it to be used in boolean contexts. The unspecified-bool-type is typically defined as a pointer to function, or pointer to member-function, to disallow accidental matching to bool function overloads.
In C++0x the idiom is to use explicit operator bool() const;, which disallows implicit conversions (such as function calls, conversions to int for arithmetic, and so on), but still allows the shared_ptr to be converted to bool in boolean contexts.
shared_ptr has operator bool(), which returns true if it is not empty.
For example, this is Microsoft implementation of shared_ptr::operator bool(): http://msdn.microsoft.com/en-us/library/bb982901.aspx
shared_ptr::operator boolean-type - Tests if an owned resource exists.

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.