在C中,NULL通常#defined为0或((void *)0)。我期望这在C ++中是相似的,并且关于堆栈溢出的许多答案似乎也表明了这种情况。但是,当我尝试编译以下程序时:
#include <stdio.h>
void f(int x) {
printf("void *\n");
}
void f(void *x) {
printf("int\n");
}
int main(void) {
f(0); // int
f((void *)0); // void *
f(nullptr); // void *
f(NULL); // why is this ambiguous?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器告诉我这f(NULL)是模棱两可的。具体来说,我的编译器说:
sample.cpp:15:5: error: call to 'f' is ambiguous
f(NULL);
^
sample.cpp:3:6: note: candidate function
void f(void *x) {
^
sample.cpp:7:6: note: candidate function
void f(int x) {
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
如果NULL被定义为0或((void *)0),我希望它能够解决的int重载或void *重载f,但事实并非如此。如果NULL被定义为nullptr出于某种原因,那也将解决void *过载问题。是什么赋予了?
我在Mac上与g++ --std=c++11 sample.cpp任何试图复制此代码的人进行了编译。还没有在其他平台上尝试过。
有关NULL在C ++ 中讨论的答案的示例,请参见此处。
编辑:我知道要始终使用nullptr过NULL的时候可能在C ++中。当我尝试提出一些为什么要向某人展示的例子时,就出现了这个问题。
从cppreference自C ++ 11开始:
值为零或类型为pr的整数文字
std::nullptr_t
在您的平台上,如果添加long int重载,似乎可以解决歧义。因此,我假设NULL在您的平台上带有这些标志的是a long int,其值为0或0l:demo。我不知道为什么他们选择0l了just 0,但是它是一个整数文字,值为零,因此这似乎是允许的。
这意味着该程序的结果取决于您的编译器和编译标志,因此请注意。nullptr优选使用。