为什么模板内部的类型检查更严格?

Eme*_*pon 7 c++ templates types overloading c++11

我正在阅读S. Meyers的Effective Modern C++,我找到了一些我无法理解的东西.

第8项解释了为什么nullptr应该优先于0NULL.赞成的主要论点nullptr是在超载决议中更安全的行为.在实践中,你可以避免指针和整数类型之间的意外混淆,但这不是我的问题.

要了解我的实际问题,请考虑以下代码,该代码基于本书中使用的示例:

#include <memory>

class MyClass {
    int a;
};

// dummy functions that take pointer types
int    f1(std::shared_ptr<MyClass> spw){return 1;};  
double f2(std::unique_ptr<MyClass> upw){return 1.0;};
bool   f3(MyClass* pw){return true;};

// template that calls a function with a pointer argument
template<typename FuncType,
         typename PtrType>
auto CallFun(FuncType func, PtrType ptr) -> decltype(func(ptr))
{
    return func(ptr);
}

int main()
{
    // passing null ptr in three different ways
    // they all work fine int this case
    auto result1 = f1(0);        // pass 0 as null ptr to f1
    auto result2 = f2(NULL);     // pass NULL as null ptr to f2
    auto result3 = f3(nullptr);  // pass nullptr as null ptr to f3 }

    // passing null ptr in three different ways through the template
    // only nullptr works in this case
    auto result4 = CallFun(f1, 0);         // compile error!
    auto result5 = CallFun(f2, NULL);      // compile error!
    auto result6 = CallFun(f3, nullptr);   // OK

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

前三直接调用f1,f2f3编译罚款或者0,NULLnullptr作为一个空指针.随后通过模板函数执行的3次调用CallFun更加挑剔:您必须使用nullptr,否则将不接受整数类型(0NULL)之间的转换.换句话说,类型检查在模板内部发生时似乎更严格.有人可以澄清发生了什么吗?

KAB*_*ult 7

CallFun推导出PtrTypefor 0NULLas 的类型int,它不会隐式转换为指针类型.

如果你要明白我的意思,只是尝试存储0NULLauto"d可变第一,并调用f1f2那些变量.他们不会编译.

0并且NULL它们本身隐式地转换为指针类型,因为它们是我猜的字面值.在标准中可能有一些关于它的东西,但我认为你明白了.

  • [support.types]/3:"宏NULL是一个实现定义的C++空指针常量".[conv.ptr]/1:"空指针常量是值为零的整数文字或类型为`std :: nullptr_t`的prvalue". (2认同)