从 const 字符串到 bool 的隐式强制转换 [duplicate]

Implicit cast from const string to bool [duplicate]

提问人:Davidius 提问时间:5/17/2017 更新时间:5/17/2017 访问量:2927

问:

我有以下代码:

#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?

C++ ++ G++的4.9

评论


答:

1赞 user7860670 5/17/2017 #1

“1”是一个字符串文字,即转换为指针,然后转换为 .请注意,此路径优先于临时对象的隐式构造。charboolstd::string

9赞 Bathsheba 5/17/2017 #2

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

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

编译器必须支持用户定义的转换序列,即来自 .std::stringconst char*

过载的存在是一条红鲱鱼。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;
}

取而代之的是。然后,编译器将优先使用 for 而不是模板(因为这是重载解析的要求之一)。好!std::stringconst char[N]

1赞 Stephan Lechner 5/17/2017 #3

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