考虑下面的代码:

#include <iostream>
#include <memory>

void f(std::shared_ptr<int> sp) {}

template <typename FuncType, typename PtrType>
auto call_f(FuncType f, PtrType p) -> decltype(f(p))
{
    return f(p);
}

int main()
{
    f(0); // doesn't work for any other int != 0, thanks @Rupesh
    // call_f(f, 0); // error, cannot convert int to shared_ptr
}

main()的第一行中,整数0转换为std::shared_ptr<int>,并且调用f(0)成功,没有任何问题。但是,使用模板调用函数会使情况有所不同。第二行将不再编译,错误是
error: could not convert 'p' from 'int' to 'std::shared_ptr<int>'

我的问题是:
  • 为什么第一个调用成功而第二个没有成功?我在这里想念什么吗?
  • 我也不明白如何在调用int中执行从std::shared_ptrf(0)的转换,因为std::shared_ptr看起来只有唯一的构造函数。

  • PS:此示例的一种变体出现在Scott Meyers的Effective Modern C++ Item 8中,作为一种使用nullptr保护此类调用的方法。

    最佳答案

    std::shared_ptr具有一个采用std::nullptr_t的构造函数,文字0是一个空指针常量,可以从C++标准草案4.10 [conv.ptr]转换为std::nullptr_t(着重于我的观点):



    在第二种情况下,p被推导为int类型,尽管其值为零,但不再是空指针常量,因此不适合相同的情况。

    作为T.C.指出用DR 903更改了措词,它要求一个整数文字,其值是零,而整数常量表达式的值是零:

    10-08 08:21
    查看更多