在C中,NULL
通常为#defined
或0
的{{1}}。我期望这在C ++中是类似的,并且关于堆栈溢出的许多答案似乎也表明情况如此。但是,当我尝试编译以下程序时:
((void *)0)
我的编译器告诉我#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;
}
不明确。具体来说,我的编译器说:
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.
定义为NULL
或0
,我希望它可以解决((void *)0)
重载或int
重载的问题。 {1}},但不是。如果出于某种原因将void *
定义为f
,那也将解决NULL
重载。有什么作用?
我在Mac上使用nullptr
进行了编译,以供任何尝试复制此文件的人使用。还没有在其他平台上尝试过。
有关在C ++中讨论void *
的答案的示例,请参见here。
编辑:我知道在C ++中尽可能在g++ --std=c++11 sample.cpp
上使用NULL
。当我尝试提出一些为什么要向某人展示的例子时,就出现了这个问题。
答案 0 :(得分:9)
从cppreference开始,从C ++ 11开始:
值为零或
std::nullptr_t
类型的prvalue的整数文字。
在您的平台上,如果添加一个long int
重载,它似乎可以解决歧义。因此,我假设您平台上带有这些标志的NULL
是值为{0或long int
:demonstration的0l
。我不知道他们为什么选择0l
而不是0
,但是它是一个整数文字,其值为零,因此这似乎是允许的。
这意味着该程序的结果取决于您的编译器和编译标志,请当心。最好使用nullptr
。