0或NULL的问题
0和NULL都不具备指针型别,因此使用0和NULL对f()进行调用不会调用f(void*) 。
void f(int);
void f(bool);
void f(void*);
f(0); // 调用f(int)
f(NULL);
使用NULL作为函数形参的本意通常是使用空指针作为形参,然而当我们重载和参数为整型与指针的函数时,使用NULL作为形参无法通过编译(以GNU为例)。
这是由于NULL不具备指针型别,在C语言的实现中,NULL可能被实现为指针,而在C++中则不会。
以下代码摘自http://cplusplus.com 。
e.g.
#include <cstddef>
#include <type_traits>
#include <iostream>
class S;
int main()
{
int* p = NULL;
int* p2 = static_cast<std::nullptr_t>(NULL);
void(*f)(int) = NULL;
int S::*mp = NULL;
void(S::*mfp)(int) = NULL;
if (std::is_same_v<decltype(NULL), std::nullptr_t>) {
std::cout << "NULL implemented with type std::nullptr_tn";
} else {
std::cout << "NULL implemented using an integral typen";
}
}
// 输出:NULL implemented using an integral type
由此可看出,C++中的NULL可能是以整型实现的。
使用nullptr的优点
准确调用重载函数
nullptr不具备整型型别,同时也不具备指针型别。
nullptr的型别为std::nullptr_t 。
因此:
f(nullptr) // 调用f(void*)版本
明确返回值的类型
使用auto初始化函数返回值时,使用nullptr进行接下来的操作也更为准确
auto result = findRes();
if(result == 0){ // 1
...
}
if(result == nullptr){ // 2
...
}
对于表达式1,无法明确返回值为整型或指针;而对于表达式2,不存在多意性 。