#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>'
我的问题是:
>为什么第一次通话成功而第二次通话没有?这里有什么我想念的吗?
>我也不理解如何在调用f(0)中执行从int到std :: shared_ptr的转换,因为它看起来像std :: shared_ptr只有显式构造函数.
PS:这个例子的变体出现在Scott Meyers的Effective Modern C Item 8中,作为用nullptr保护这种调用的一种方式.
解决方法
A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t. A null pointer constant can be converted to a
pointer type; the result is the null pointer value of that type and is
distinguishable from every other value of object pointer or function
pointer type. Such a conversion is called a null pointer conversion.
Two null pointer values of the same type shall compare equal. The
conversion of a null pointer constant to a pointer to cv-qualified
type is a single conversion,and not the sequence of a pointer
conversion followed by a qualification conversion (4.4). A null
pointer constant of integral type can be converted to a prvalue of
type std::nullptr_t. [ Note: The resulting prvalue is not a null
pointer value. —end note ]
在第二种情况下,p被推导为类型int,虽然值为零但不再是空指针常量,因此不适合相同的情况.
作为T.C.指出措辞已经改变了DR 903,这需要一个零值为零的整数文字而不是一个计算为零的整数常量表达式:
A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type.