考虑下面的代码。
void f(double p) {}
void f(double* p) {}
int main()
{ f(1-1); return 0; }
MSVC 2017不会对此进行编译。它表明存在一个模棱两可的重载调用,因为
1-1
与0
相同,因此可以转换为double*
。其他技巧,例如0x0
,0L
或static_cast<int>(0)
也不起作用。甚至声明const int Zero = 0
并调用f(Zero)
也会产生相同的错误。仅当Zero
不是const
时,它才能正常工作。看起来同一问题适用于GCC 5及以下版本,但不适用于GCC6。我很好奇这是否是C++标准的一部分,已知的MSVC错误或编译器中的设置。粗略的Google并未产生结果。
最佳答案
MSVC认为1-1
是一个空指针常量。这对于C++ 03的标准是正确的,在C++ 03中,所有具有0
值的整数常量表达式都是空指针常量,但是它进行了更改,以便对于带有CWG issue 903的C++ 11,只有零个整数常量是空指针常量。如您在示例中以及标准中所记录的那样,这是一个重大更改,请参阅C++ 14标准(N4140草稿)的[diff.cpp03.conv]。
MSVC仅在一致性模式下应用此更改。因此您的代码将使用/permissive-
标志进行编译,但我认为更改仅在MSVC 2019中实现,请参见here。
对于GCC,GCC 5默认为C++ 98模式,而GCC 6和更高版本默认为C++ 14模式,这就是行为更改似乎取决于GCC版本的原因。
如果使用空指针常量作为参数调用f
,则该调用是模棱两可的,因为可以将空指针常量转换为任何指针类型的空指针值,并且此转换与int
(或任何整数)的转换具有相同的等级。类型)到double
。
关于c++ - 整数->指针转换规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60824270/