The code below prints 'operator bool' when used in the if statement and 'operator void*' when it needs a bool for function call.
Why isn't it using operator bool
for the function call too? And how to make it use it in both cases?
#include <iostream>
class A
{
public:
explicit operator bool() const
{
std::cout << "operator bool" << std::endl;
return true;
}
operator void*() const
{
std::cout << "operator void*" << std::endl;
return 0;
}
};
void f(bool valid)
{
std::cout << "f called " << valid << std::endl;
}
int main(int argc, char *argv[])
{
A a;
if(a)
std::cout << "if a" << std::endl;
f(a);
return 0;
}
In an if
statement, implicit and explicit conversion operators are considered. Because A
has an operator bool
, it chooses that one, as it is a better match than converting A
to a void*
and then converting that to bool
.
But in every other statement, which are not conditions (if
, while
, ...), the explicit conversion operators do not participate in overload resolution, and the only valid operator then is operator void*
, which can be used because there is an implicit conversion from pointers to bool
.
If you want operator bool
to be selected, you need make it non-explicit
, or use a cast (because that's what marking it explicit
means, making sure that one has to be explicit to use it):
f(static_cast<bool>(a));
The reason is that the operator is declared with the function specifier explicit
.
In the condition of the if statement the value is contextually converted to the type bool.
From the C++ Standard (4 Standard conversions)
2 [ Note: expressions with a given type will be implicitly converted to other types in several contexts:
...
— When used in the condition of an if statement or iteration statement (6.4, 6.5). The destination type is bool.
However when the value is passed to the function as an argument there is used the so-called copy initialization. In this case the function specifier explicit prevents converting to the type bool.
From the C++ Standard (12.3.2 Conversion functions)
2 A conversion function may be explicit (7.1.2), in which case it is only considered as a user-defined conversion for direct-initialization (8.5). Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
A simple way to force calling the bool operator is the following
f( bool( a ) );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With