Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bool vs void* casts on the same object

Tags:

c++

casting

c++11

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;
}
like image 391
unvadim Avatar asked Jul 26 '17 08:07

unvadim


2 Answers

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));
like image 175
Rakete1111 Avatar answered Oct 26 '22 03:10

Rakete1111


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 ) );
like image 5
Vlad from Moscow Avatar answered Oct 26 '22 03:10

Vlad from Moscow