C++,bool转换是否总是回退到隐式转换为void*?

jen*_*nsa 17 c++ void-pointers implicit-conversion

问题:隐式bool转换是否总是回退到尝试隐式转换为void*?(如果存在类型的转换函数).如果是这样,为什么?

考虑以下简短程序:

#include <iostream>

class Foo{
public:

    operator void*() const
    {
        std::cout << "operator void*() const" << std::endl;
        return 0;
    }
};

int main()
{
    Foo f;

    if(f)
        std::cout << "True" << std::endl;
    else
        std::cout << "False" << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是:

operator void*() const
False
Run Code Online (Sandbox Code Playgroud)

意思是,void*被称为转换函数.如果我们explicit在转换函数前面标记限定符,则隐式转换void*将失败.

编辑: 似乎很多答案是"空指针可以转换为false".我理解这一点,我的问题是关于"如果我不能直接调用operator bool()那么我将尝试转换为任何指针".

Leo*_*eon 16

如果编译器无法直接将用户定义的类型转换为bool它,那么它会尝试间接地执行此操作,即将(通过用户定义的转换)转换为可以转换为的类型,bool而不涉及另一个用户定义的转换.这些类型的列表包括(并且似乎仅限于)以下类型:

  • 的整数运算类型(char,int等)
  • 一个浮点运算类型(float,double,long double)
  • 指针类型(void*属于这里,但它也可以const std::vector<Something>*)
  • 指向函数的指针(包括指向成员函数的指针)
  • 任何上述参考类型

但请注意,只有一个这样的间接转换必须存在.如果上述列表中的两次或多次转换成为可能,则编译器将面临歧义并报告错误.


pep*_*ppe 6

对于标准中的一些参考:

  • §6.4.0.4[stmt.select]

    作为表达式的条件的值是表达式的值,上下文转换bool为除了以外的语句switch

  • §4.0.4[转]

    某些语言结构要求将表达式转换为布尔值.e出现在这样的上下文中的表达被称为在上下文中被转换为bool并且当且仅当声明bool t(e);格式良好时,对于一些发明的临时变量而言是良好形成的t.

  • §8.5.17[dcl.init]

    初始化器的语义如下.的目标类型是对象或引用的类型被初始化和源类型是初始化表达式的类型.

  • §8.5.17.7[dcl.init]

    否则,如果源类型是(可能是cv限定的)类类型,则考虑转换函数.列举了适用的转换函数(13.3.1.5),并通过重载决策(13.3)选择最佳函数.调用如此选择的用户定义转换以将初始化表达式转换为正在初始化的对象.如果转换不能完成或不明确,则初始化是错误的.

  • §13.3.1.5[over.match.conv]

    假设"cv1 T"是要初始化的对象的类型,并且"cv S"是初始化表达式的类型,并且S是类类型,则候选函数选择如下:

    考虑S及其基类的转换函数.那些未隐藏在其中的非显式转换函数S和yield类型T或可T通过标准转换序列(13.3.3.1.1)转换为类型的类型是候选函数.对于直接初始化,那些未隐藏在其中的显式转换函数S和yield类型T或可转换为T具有限定转换类型的类型(4.4)也是候选函数.

  • §4.13.1[conv.bool]

    算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为类型的prvalue bool.将零值,空指针值或空成员指针值转换为false; 任何其他值都转换为true.