C++11 为什么g++;4.x允许在作为参数传递时将nullptr隐式转换为其他类型,但>;5.x不要?

C++11 为什么g++;4.x允许在作为参数传递时将nullptr隐式转换为其他类型,但>;5.x不要?,c++11,gcc,g++,nullptr,C++11,Gcc,G++,Nullptr,我的理解是,nullptr不能隐式转换为其他类型。但后来我“发现”它可以转换成布尔。 问题是,我可以看到它在GCC4.x上被转换成bool,但它在GCC4.x上抱怨 #include <iostream> bool f(bool a){ return !a; } // Type your code here, or load an example. int main() { return f(nullptr); } #包括 布尔f(布尔a){ 返回!a; } //在

我的理解是,nullptr不能隐式转换为其他类型。但后来我“发现”它可以转换成布尔。 问题是,我可以看到它在GCC4.x上被转换成bool,但它在GCC4.x上抱怨

#include <iostream>
bool f(bool a){
    return !a;
}
// Type your code here, or load an example.
int main() {
    return f(nullptr);
}
#包括
布尔f(布尔a){
返回!a;
}
//在此处键入代码,或加载示例。
int main(){
返回f(nullptr);
}
在>5.x时,我得到

<source>: In function 'int main()':

<source>:7:21: error: converting to 'bool' from 'std::nullptr_t' requires direct-initialization [-fpermissive]
     return f(nullptr);

             ^

<source>:2:6: note:   initializing argument 1 of 'bool f(bool)'
 bool f(bool a){

      ^
Compiler returned: 1
:在函数“int main()”中:
:7:21:错误:从“std::nullptr\u t”转换为“bool”需要直接初始化[-fppermissive]
返回f(nullptr);
^
:2:6:注意:初始化'bool f(bool)'的参数1
布尔f(布尔a){
^
返回的编译器:1
我在GCC 5.X的发行说明中找不到任何可以解释这一点的东西

在这里可以看到:


有人能解释一下为什么版本之间存在差异,以及这里应用了什么规则。

该规则可以在C++17[conv.bool]/1中找到:

对于直接初始化,可以使用类型为
std::nullptr\u t
的PR值 将转换为类型为
bool
的PR值;结果值为false

函数参数初始化是复制初始化,不是直接初始化。如果你不熟悉这个主题,C++中的初始化上下文可以分为这两类,并且只有直接初始化才有一些操作。 在C++14中增加了对直接初始化的限制,这可以解释g++版本之间的差异

我假设此规则的目的是为您编写的确切代码引发一个错误:需要一个
bool
,并且提供了一个空指针常量;测试空指针常量的布尔性不是很有意义,因为它只具有一个状态

请记住,
nullptr
不是指针;如果代码明确要求这样的转换,它可以隐式转换为空指针。添加它的全部原因是为了修复
0
被用作空指针常量的问题,以及无意中匹配其他模板或重载的问题

代码可以是:

return f(static_cast<bool>(nullptr));
返回f(静态_cast(nullptr));
或者,您可以添加一个重载
f
,该重载接受
std::nullptr\t