我用 3 个编译器测试了以下代码,得到了 3 个不同的结果:错误、警告和正常。
- GCC (5.3):错误:从“std::nullptr_t”到“const Thing&”的无效用户定义转换
- Clang (3.8):警告:将 nullptr 常量隐式转换为“bool”
- MSVC (14.1):没有错误,没有警告
哪个编译器是正确的?我知道这是指针类型和 bool
之间的简单转换。但是 std::nullptr_t
和 bool
是怎么回事?
(最后,Clang 和 MSVC 都可以处理代码。从积极的角度来看,Clang 稍微有点冗长。)
struct Thing
{
Thing(bool) {}
};
void addThing(const Thing&){}
int main()
{
addThing(nullptr); // warning or error on this line
}
最佳答案
这是无效的。根据boolean conversions的规则:
A prvalue of type
std::nullptr_t
, includingnullptr
, can be converted to a prvalue of typebool
in context of direct-initialization. The resulting value isfalse
.
标准引述,§7.14/1 Boolean conversions [conv.bool]
For direct-initialization, a prvalue of type
std::nullptr_t
can be converted to a prvalue of typebool
; the resulting value isfalse
.
转换只允许direct-initialization , 但不是 copy-intialization ,其中包括按值将参数传递给函数的情况。例如
bool b1 = nullptr; // invalid
bool b2 {nullptr}; // valid
所以 GCC 是正确的。但是 Clang 也没有错;该标准只要求编译器在程序格式错误时“发出诊断”,因此它必须告诉您发生了什么事情,之后它可以做任何事情。
参见 Does the C++ standard specify that for some cases the compiling should fail with an error?
关于c++ - 从 nullptr_t 到 bool : valid or not? 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43803368/