MarsPlus
MarsPlus

Reputation: 321

C++ conversion operator

In following code:

if ( cin >> x ) { /* ... */ }

the standard library define an operator conversion operator void*, which converts type istream to void*. However, if the if tests a condition, why the standard library doesn't define a conversion from type istream to type bool? Or is there any implicit consideration behind the implementation?

Upvotes: 2

Views: 287

Answers (2)

rodrigo
rodrigo

Reputation: 98348

The operator bool() has always been a bit problematic. The main problem is that bool in C++ is an arithmetic operator, so any class that implements operator bool() will automatically be convertible to int.

Thus, the following code would be legal, but quite meaningless:

cout << (2 * cin);

The designers of the standard library thought that the operator less likely to cause problem, while at the same time being able to be converted to bool would be operator void*. The idea is that a void*, as is, cannot be used for anything.

That said, other more modern libraries, such as boost sometimes use the following idiom:

typedef void *this_type::*unspecified_bool_type;

operator unspecified_bool_type() const { return ... ; }

That is, instead of bool or void* they use a pointer-to-member-function, that will be truly useless other than being converted to bool.

That said, with C++11, the designers of the language noticed this problem and designed the following solution:

explicit operator bool() const
{ return ...; }

Now, this operator will only be called when the object is in a truly bool context (if, while...) , not in any random integral operation.

Upvotes: 3

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153810

The simple reason is that you don't want to accidentally end up with a conversion to an int. For example, assume there is an implicit conversion to bool and you wrote

if (std::cin << x) { /* ... */ }

The compiler couldn't catch the obvious error (using << instead of >>) because the implicit conversion would convert to int and happily shift the result. That is almost certainly not what is intended. A void* can't be shifted, i.e., the compiler would yield an error instead.

Prior to C++11 there was no way to mark conversion operators explicit. You could only mark conversion constructors as explicit. In C++11 the conversion operator for streams was actually changed to an explicit conversion to bool as the conversion to void* had a few problems, too.

Upvotes: 8

Related Questions