从 const string 到 bool 的隐式转换

Implicit cast from const string to bool

我有以下代码:

#include <iostream>
#include <string>

void foo(bool a)
{
        std::cout << "bool" << std::endl;
}

void foo(long long int a)
{
        std::cout << "long long int" << std::endl;
}

void foo(const std::string& a)
{
        std::cout << "string" << std::endl;
}

int main(int argc, char* args[])
{
        foo("1");
        return 0;
}

执行时我得到这个输出:

bool

我期望的输出是:

string

为什么 g++ 4.9 将此字符串隐式转换为 bool?

"1" 是一个字符串文字,即 char 的数组,先转换为指针,然后再转换为 bool。请注意,此路径优于临时 std::string 对象的隐式构造。

您的编译器正在正确解释标准。是的,这是一个棘手的极端案例,很多面试官都会问,所以他们看起来比实际更聪明。

路由const char[2](文字"1"的形式类型)到const char*bool是一个标准转换序列,因为它只使用内置类型。

您的编译器必须支持用户定义的转换序列,即。来自 const char*.

std::string 构造函数

过载的存在 void foo(long long int a) 是一个转移注意力的问题。

您可以在 C++11 中通过将重载降低到 bool 并编写

来优雅地解决这个问题
#include <type_traits>
template <
    typename Y,
    typename T = std::enable_if_t<std::is_same<Y, bool>{}>
>
void foo(Y)
{
  std::cout << "bool" << std::endl;
}

取而代之。然后,编译器将支持 std::string for const char[N] 而不是模板(因为这是重载决议的要求之一)。不错!

"1" 是一个字符串文字,当用作函数参数时,它会衰减为 const char* 类型的指针。由于函数 foo 没有采用 const char* 的重载,但是存在从 const char*bool 的标准转换,它回落到 foo(bool)。请注意,当指针值作为布尔参数时,其解释类似于 somePtr==nullptr ? false : true