将 NULL 作为参数传递时,函数重载如何工作? [英] How does function overloading work when passing NULL as argument?

查看:64
本文介绍了将 NULL 作为参数传递时,函数重载如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 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.

使用 nullptr 有哪些优势?

推荐答案

我知道 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 *) 因为甚至没有任何从 nullptrint<的转换/code>
  • callMe(NULL) 取决于 NULL 的定义方式.如果 0nullptr,请参见上文.如果 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 from nullptr to int
  • callMe(NULL) depends on how NULL is defined. If 0 or nullptr, see above. If 0L 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆