【问题标题】:Why is type checking inside templates more strict? [duplicate]为什么模板内的类型检查更严格? [复制]
【发布时间】:2015-05-14 12:16:07
【问题描述】:

我正在阅读 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;
}

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

【问题讨论】:

  • 我问了完全相同的问题 :) 请参阅我放置的欺骗链接,另请参阅标准引号。

标签: c++ templates c++11 types overloading


【解决方案1】:

CallFun0NULLPtrType 类型推导出为int,不会隐式转换为指针类型。

如果您想了解我的意思,请先尝试将0NULL 存储在auto'd 变量中,然后从这些变量中调用f1f2。他们不会编译。

0NULL 本身隐式转换为指针类型,因为我猜它们是文字值。标准中可能有一些关于它的内容,但我认为你明白了。

【讨论】:

  • 值得注意的是,decltype(NULL) 可能不是每个编译器上的int。唯一的要求是文字可以隐式转换为任何指针类型,因此NULL 可以定义为nullptr
  • [support.types]/3:“宏 NULL 是实现定义的 C++ 空指针常量”。 [conv.ptr]/1:“空指针常量是一个整数文字,其值为 0 或类型为 std::nullptr_t 的纯右值”。
猜你喜欢
  • 2020-06-12
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 2017-01-06
  • 2020-10-30
  • 2015-11-18
相关资源
最近更新 更多