从const string到bool的隐式类型转换

5

我有以下代码:

#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会将这个字符串隐式转换为布尔值?
3个回答

9

你的编译器正确地解释了标准。是的,这是一个棘手的边角案例,许多面试官都会问到这个问题,以显示他们比实际更聪明。

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代替const char[N]的模板(因为这是重载决议的要求之一)。棒极了!


1
"

\"1\"是一个字符串字面量,它是char数组,会被转换为指针,然后转换为bool。请注意,这种路径优于隐式构造临时的std::string对象。

"

1
""1" 是一个字符串字面值,当作为函数参数使用时会衰减为 const char* 类型的指针。由于函数 foo 没有接受 const char* 参数的重载函数,但是从 const char*bool 存在标准转换,因此它退化到了 foo(bool)。请注意,当将指针值作为 bool 参数时,它被解释为 somePtr==nullptr ? false : true。"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接