【问题标题】:Why isn't it necessary to specialize for `std::nullptr_t` if there's a specialized function AND a templated function如果有专门的函数和模板函数,为什么不需要专门针对`std::nullptr_t`
【发布时间】:2018-02-02 07:51:55
【问题描述】:

考虑以下代码:

#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 确实 not 抛出关于模糊重载解析的错误,因为我认为 nullptr 和 NULL 可以放入 any 指针类型,包括从模板专门化的fun(int*),前提是没有专门针对std::nullptr_t 的重载。

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

【问题讨论】:

  • @Someprogrammerdude 感谢格式化帮助。
  • 这个是相关的,但可能离你的问题有点太远了,不是骗子:stackoverflow.com/questions/10291405/…
  • 请在if语句中添加return语句,否则s == nullptr时行为未定义
  • @krzaq 添加。谢谢。
  • 因为T无法推断;应该是什么?

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


【解决方案1】:

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

尽管这违反直觉,但以下断言不会触发:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多