bool vs void*在同一个对象上施放

unv*_*dim 21 c++ casting c++11

下面的代码在if语句中使用时会输出'operator bool',而在需要bool进行函数调用时会输出'operator void*'.

为什么它也不operator bool用于函数调用?以及如何在两种情况下使用它?

#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;
}
Run Code Online (Sandbox Code Playgroud)

Rak*_*111 21

if语句中,考虑隐式和显式转换运算符.因为A有一个operator bool,它选择那个,因为它比转换A为a void*然后将其转换为更好的匹配bool.

但是在其他语句中,不是条件(if,while...),显式转换运算符不参与重载解析,而且唯一有效的运算符则operator void*可以使用,因为存在从指针到指针的隐式转换bool.

如果你想operator bool被选中,你需要将其设为非explicit,或者使用强制转换(因为这就是标记它的explicit含义,确保必须明确使用它):

f(static_cast<bool>(a));
Run Code Online (Sandbox Code Playgroud)

  • @unvadim那是因为非`constst`成员函数总是比`const`更好匹配(促进`const`必须发生). (2认同)

Vla*_*cow 5

原因是使用函数说明符声明了运算符explicit.

在if语句的条件下,该值在上下文中转换为bool类型.

来自C++标准(4个标准转换)

2 [注意:具有给定类型的表达式将在多个上下文中隐式转换为其他类型:

...

- 在if语句或迭代语句(6.4,6.5)的条件下使用时.目的地类型是bool.

但是,当值作为参数传递给函数时,会使用所谓的复制初始化.在这种情况下,函数说明符显式阻止转换为bool类型.

来自C++标准(12.3.2转换函数)

2 转换函数可以是显式的(7.1.2),在这种情况下,它仅被视为用户定义的直接初始化转换 (8.5).否则,用户定义的转换不限于在分配和初始化中使用.

强制调用bool运算符的一种简单方法如下

f( bool( a ) );
Run Code Online (Sandbox Code Playgroud)