如果有专门的函数和模板函数,为什么没有必要专门研究`std :: nullptr_t`

时间:2018-02-02 07:51:56

标签: c++ null language-lawyer overload-resolution nullptr

请考虑以下代码:

#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 引发有关模糊重载决策的错误,因为我认为nullptrNULL可能适合< em>任何指针类型,包括模板专用的fun(int*),前提是不存在专门用于std::nullptr_t的重载。

为什么fun(nullptr)fun(NULL)直接解析为fun(const char *)

1 个答案:

答案 0 :(得分:5)

std::nullptr_t不是指针,因此它不会在函数模板中与T*进行模式匹配。

由于这是违反直觉的,下面的断言不会触发:

static_assert(std::is_pointer<std::nullptr_t>() == false);

至于NULL,它是一个实现定义的宏。如果要相信cppreference,它可以是值为零的整数文字(因此不是指针),也可以是类型std::nullptr_t的prvalue,如上所述。 不是一个void*指针。