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.
Related
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.
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.
I'm curious how the fstream class is able to return a true or false value by simply placing the name of the object inside a conditional statement. For example...
std::fstream fileStream;
fileStream.open("somefile.ext");
if (!fileStream) // How does this work?
std::cout << "File could not be opened...\n";
I ask this because I want my own class to return a value if I use it in a similar way.
It's not really that it is equal to true or false, but rather that it overloads the ! operator to return its status.
See http://www.cplusplus.com/reference/iostream/ios/operatornot/ for the details.
Doing this yourself is very simple, check out the operator overloading faq or C++ Operator Overloading Guidelines.
Edit:
It's been pointed out to me that ios also overloads the void * conversion operator, returning a null pointer in the case of a failure. So you could also use that approach, also covered in the previously mentioned faq.
This works using a conversion operator. Note that the seemingly obvious way, conversion to bool, has unintended side effects, therefore a conversion to a built-in type with implicit conversion to bool should be used, e.g.:
class X
{
public:
void some_function(); // this is some member function you have anyway
operator void(X::*)() const
{
if (condition)
return &X::some_function; // "true"
else
return 0; // "false"
}
};
In C++11, you can make the conversion to bool explicit, and thus avoid the unintended side effects. Thus in C++11 you can simply write:
class X
{
public:
explicit operator bool() const
{
return 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.
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.