c++ - 将 NULL 作为参数传递时,函数重载如何工作?

标签 c++ c++11 overloading overload-resolution

我知道 NULL 被#defined 为 0。它似乎是一个被转换为指针类型的 int 常量。那么当有两个重载函数时会发生什么:一个采用指针类型,另一个采用 int 类型。这与 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) 会调用哪个函数呢?我在我的电脑上编译了这段代码。只有一个警告。

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。

但是,当我尝试在在线 GeeksForGeeks IDE 上编译我的代码时,我遇到了一些编译器错误。

https://ide.geeksforgeeks.org/UsLgXRgpAe

我想知道为什么会出现这些错误。

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都出现同样的错误。这是实际定义的行为吗?

这个场景呢?哪些函数会在这里被调用?

#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;
}

一个更笼统的问题,但我认为这就是问题所在:你怎么知道重载函数时哪些函数调用不明确?我想知道答案这个问题是在有多个功能竞争的情况下提出的。如果只有一个函数,它会毫无错误地接受参数。但是,当几个函数似乎同样可能接受该论点时会发生什么?

链接的问题是关于在 C 中使用 NULL。我的问题是关于 C++。 C 编程语言没有运算符重载,因此我提到的大多数问题只是 C++ 特定的问题。

============================================= ============================

这是一个相关问题,详细解释了问题及其解决方案。里面有很多有用的答案。

What are the advantages of using nullptr?

最佳答案

I know that NULL is #defined to be 0.

这通常不是真的,它可以被定义为nullptr。它可以是 0L。还有其他可能性,例如我试过的一个 gcc 版本将它定义为 __null,这显然是 gcc 的空指针常量扩展。

How do you know which function calls are ambiguous or not when overloading functions?

通过阅读 C 标准的重载解决方案部分。这是其中最复杂的部分之一。简而言之,对不同的转换序列进行排序,一些转换序列的排序高于其他转换序列。有介绍on cppreference .

  • callMe(0) 解析为 (int),因为完全匹配优于转换。 (调用(int *)版本需要整数到指针的转换)
  • callMe(nullptr) 解析为 (int *) 因为甚至没有任何从 nullptrint< 的转换
  • callMe(NULL) 取决于 NULL 的定义方式。如果是 0nullptr,请参见上文。如果 0L 则它是不明确的,因为需要转换来匹配任何一种情况,并且整数转换与整数到指针的转换具有相同的等级。等

关于c++ - 将 NULL 作为参数传递时,函数重载如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51391703/

相关文章:

c++ - 为什么QTextDocument背景颜色仅更改一次?

c++ - 使用函数 <void (boost::any)> 的事件系统是个好主意?

c++ - 我如何(或者我可以安全地,或者我可以) move 一个 const 对象?

c++ - 通过 std::function 包装重载函数

c++ - 重载调用 *** <未解析的重载函数类型>)' 不明确

c++ while循环不会在错误条件下退出

c++ - luabind:无法访问全局变量

c++ - 为什么是 -0.x^0.x -nan(ind)

c++ - 为什么 observer_ptr 在 move 后不归零?

c++ - 具有多个函数和多个转换运算符的重载解决方案