请考虑以下代码:
#include <iostream>
using namespace std;
void fun(const char* s){
if (s == nullptr) {
puts("const char* nullptr");
} else {
printf("%s\n", s);
}
}
template <typename T>
void fun(T* p){
printf("%p\n", p);
}
int main() {
int a;
fun("abc"); // Resolves to fun(const char*)
fun(&a); // Specializes the template to int*
fun(nullptr); // Uses fun(const char*)??
fun(NULL); // Same as above
}
我很惊讶g++ 7.2.0
不引发有关模糊重载决策的错误,因为我认为nullptr
和NULL
可能适合< em>任何指针类型,包括模板专用的fun(int*)
,前提是不存在专门用于std::nullptr_t
的重载。
为什么fun(nullptr)
和fun(NULL)
直接解析为fun(const char *)
?
答案 0 :(得分:5)
std::nullptr_t
不是指针,因此它不会在函数模板中与T*
进行模式匹配。
由于这是违反直觉的,下面的断言不会触发:
static_assert(std::is_pointer<std::nullptr_t>() == false);
至于NULL
,它是一个实现定义的宏。如果要相信cppreference,它可以是值为零的整数文字(因此不是指针),也可以是类型std::nullptr_t
的prvalue,如上所述。 不是一个void*
指针。