为什么 bool 到 string 的隐式转换不是错误?

Why implicit conversion of bool to string isn't an error?

我仔细查看并尝试在 SO 上找到类似的问题,但没有找到任何有用的信息。所以,在这里发布我的问题。

考虑这个程序:

#include <iostream>
void foo(const std::string &) {}
int main() 
{
    foo(false);
}
[Warning] converting 'false' to pointer type for argument 1 of 'std::basic_string::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]' [-Wconversion-null]

为什么 C++ 允许在没有显式转换的情况下这样做?我期待得到编译器错误。程序在运行时异常终止,异常显示如下:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_S_construct null not valid

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

标准对这种类型的隐式转换有何规定?

bool 基本上是一个整数,所以它会被解释为零,在你的情况下它可能是 0 字符,这将导致该问题,字符串将是一个异常

发生的事情是 std::string 是从 false 隐式构造的,使用 const CharT* 重载并将 false 转换为空指针。根据该构造函数的文档:

The behavior is undefined if s [the pointer] does not point at an array of at least Traits::length(s)+1 elements of CharT.

因此出现故障(以友好异常的形式出现,但不要依赖它)。

现在,它是正确的吗?根据 [conv.ptr] :

A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t.

false 确实具有零值,但不是整数文字(它是布尔文字)。因此,std::string 的构造函数采用的对 CharT* 的隐式转换是非标准的。

事实上,虽然 GCC 发出警告,但 Clang 拒绝编译它。

在 C++11 引入 nullptr 关键字之前,空指针有点像 hack。任何等于零的整数文字都可以作为空指针常量,false 符合要求。

因此,您的程序的效果是使用 NULLchar const * 参数构造 std::string。构造函数不支持空指针,所以你会得到未定义的行为。

此问题的解决方案是使用更新的 C++ 方言。如有必要,将 -std=c++11 传递给编译器,或 -std=c++14。然后你应该得到这样的东西:

error: no matching function for call to 'foo'

http://coliru.stacked-crooked.com/a/7f3048229a1d0e5a

编辑: 嗯,GCC 似乎还没有实现这个改变。这有点令人惊讶。你可以试试 Clang。

我有 filed 错误报告。