将 NULL 作为参数传递时,函数重载如何工作? [英] How does function overloading work when passing NULL as argument?
问题描述
我知道 NULL 被 #defined 定义为 0.它似乎是一个被转换为指针类型的 int
常量.那么当有两个重载函数时会发生什么:一个采用指针类型,另一个采用 int
类型.这与 nullptr
相比如何?
I know that NULL is #defined to be 0. It seems to be an int
constant that gets converted to a pointer type. So what happens when there are two overloaded functions: one takes a pointer type, another takes an int
type. How does this work vs. nullptr
?
#include <iostream>
using namespace std;
void callMe(int* p)
{
cout << "Function 1 called" << endl;
}
void callMe(int i)
{
cout << "Function 2 called" << endl;
}
int main()
{
callMe(nullptr);
callMe(NULL);
return 0;
}
我知道 callMe(nullptr)
肯定会调用第一个函数.但是callMe(NULL)
会调用哪个函数呢?我在我的电脑上编译了这段代码.只有一个警告.
I know that callMe(nullptr)
will definitely call the first function. But which function will be called by callMe(NULL)
? I compiled this code on my computer. There was only one warning.
g++ -std=c++11 nullptr_type.cpp
nullptr_type.cpp: In function 'int main()':
nullptr_type.cpp:44:14: warning: passing NULL to non-pointer argument 1 of 'void callMe(int)' [-Wconversion-null]
callMe(NULL);
^
我的代码编译没有任何问题,当我运行它时,我看到 callMe(NULL)
调用了函数 2.Visual Studio 也编译了代码并调用了函数 2.
My code compiled without any problems, and when I run it I see that callMe(NULL)
called Function 2. Visual Studio also compiles the code and it calls Function 2.
但是,当我尝试在在线 GeeksForGeeks IDE 上编译我的代码时,我遇到了一些编译器错误.
However, when I try to compile my code on the online GeeksForGeeks IDE, I get some compiler errors.
https://ide.geeksforgeeks.org/UsLgXRgpAe
我想知道为什么会出现这些错误.
I want to know why these errors occur.
prog.cpp: In function 'int main()':
prog.cpp:17:13: error: call of overloaded 'callMe(NULL)' is ambiguous
callMe(NULL);
^
prog.cpp:4:6: note: candidate: void callMe(int*)
void callMe(int* p)
^
prog.cpp:9:6: note: candidate: void callMe(int)
void callMe(int i)
^
在线 Ideone IDE 和在线 TutorialsPoint CodingGround IDE 生成相同的错误.这实际上是定义的行为吗?
The same errors are generated by the online Ideone IDE and online TutorialsPoint CodingGround IDE. Is this actually defined behavior or not?
这个场景怎么样?这里会调用哪些函数?
What about this scenario? Which functions will get called here?
#include <iostream>
using namespace std;
void callMe(int* p)
{
cout << "Function 1 called" << endl;
}
void callMe(char* cp)
{
cout << "Function 2 called" << endl;
}
void callMe(nullptr_t np)
{
cout << "Function 3 called" << endl;
}
void callMe(int i)
{
cout << "Function 4 called" << endl;
}
int main()
{
callMe(nullptr);
callMe(NULL);
return 0;
}
一个更一般的问题,但我认为这就是它的全部内容:在重载函数时,您如何知道哪些函数调用不明确?我想知道答案在有多个函数作为参数的竞争者的情况下,这个问题.如果只有一个函数,它会正确地接受参数.但是当几个函数似乎同样可能采用该参数时会发生什么?
A more general question, but I think that this is where it is all going to: How do you know which function calls are ambiguous or not when overloading functions? I want to know the answer to this question in the context where there are multiple functions which are competitors for the argument. If there would have been only one function, it would take the argument without error. But what happens when several functions seem to be equally likely to take that argument?
链接的问题是关于在 C 中使用 NULL
.我的问题是关于 C++.C 编程语言没有运算符重载,因此我触及的大部分问题都只是 C++ 特定的事情.
The linked question is about using NULL
in C. My question is about C++. The C programming language does not have operator overloading, and hence most of the issues that I touched upon are only C++ specific things.
==============================================================================
===========================================================================
这是一个相关问题,详细解释了问题及其解决方案.其中有很多有用的答案.
This is a related question which explains the issue and the solution to it in detail. There's a lot of useful answers in that one.
推荐答案
我知道 NULL 被 #defined 定义为 0.
I know that NULL is #defined to be 0.
这通常不是真的,它可以定义为nullptr
.它可能是 0L
.还有其他可能性,例如我尝试过的 gcc 版本将其定义为 __null
,这显然是 gcc 的空指针常量扩展.
This is not true in general, it could be defined to nullptr
. It could be 0L
. There are other possibilities too, e.g. a version of gcc I tried defines it to __null
which is obviously a null pointer constant extension of gcc.
在重载函数时如何知道哪些函数调用不明确?
How do you know which function calls are ambiguous or not when overloading functions?
通过阅读 C 标准的重载解析部分.这是其中最复杂的部分之一.简而言之,对不同的转换序列进行排序,并且一些转换序列比其他转换序列具有更高的等级.有一个介绍 关于 cppreference.
By reading the Overload Resolution section of the C Standard. Which is one of the most complicated parts of it. In brief, different conversion sequences are ranked and some conversion sequences have a higher rank than others. There's an introduction on cppreference.
callMe(0)
解析为(int)
因为精确匹配优于转换.(调用(int *)
版本需要整数到指针的转换)callMe(nullptr)
解析为(int *)
因为甚至没有任何从nullptr
到int<的转换/code>
callMe(NULL)
取决于 NULL 的定义方式.如果0
或nullptr
,请参见上文.如果0L
那么它是不明确的,因为需要一个转换来匹配任何一种情况,并且整数转换与整数到指针的转换具有相同的等级.等
callMe(0)
resolves to(int)
because Exact Match is preferred over Conversion. (integer to pointer conversion is required to call the(int *)
version)callMe(nullptr)
resolves to(int *)
because there is not even any conversion available fromnullptr
toint
callMe(NULL)
depends on how NULL is defined. If0
ornullptr
, see above. If0L
then it's ambiguous because a Conversion is required to match either case and integer conversion has the same rank as integer-to-pointer conversion. Etc.
这篇关于将 NULL 作为参数传递时,函数重载如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!