vso*_*tco 6 c++ type-conversion shared-ptr implicit-conversion c++11
请考虑以下代码:
#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
}
Run Code Online (Sandbox Code Playgroud)
在第一行中main()
,整数0
转换为a std::shared_ptr<int>
,调用f(0)
成功,没有任何问题.但是,使用模板调用函数会使事情变得不同.第二行将不再编译,错误是
error: could not convert 'p' from 'int' to 'std::shared_ptr<int>'
Run Code Online (Sandbox Code Playgroud)
我的问题是:
int
到std::shared_ptr
被调用执行f(0)
,因为它看起来像std::shared_ptr
只有明确的构造函数.PS:这个例子的一个变体出现在Scott Meyers的Effective Modern C++ Item 8中,作为一种保护这种调用的方式nullptr
.
std :: shared_ptr有一个构造函数,它接受std :: nullptr_t,literal 0
是一个空指针常量,可以从草案C++标准部分[conv.ptr]转换为std :: nullptr_t(强调我的前进):4.10
空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零或类型为std :: nullptr_t的prvalue.空指针常量可以转换为指针类型; 结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开.这种转换称为空指针转换.相同类型的两个空指针值应相等.将空指针常量转换为指向cv限定类型的指针是单个转换,而不是指针转换的序列,后跟限定转换(4.4).可以将整数类型的空指针常量转换为std :: nullptr_t类型的prvalue.[注意:生成的prvalue不是空指针值. - 尾注]
在你的第二种情况下p
推断为int类型,虽然值为零但不再是空指针常量,因此不适合相同的情况.
正如TC指出的那样,措辞是用DR 903改变的,它需要一个值为零的整数文字,而不是一个计算为零的整数常量表达式:
空指针常量是值为零的整数文字(2.14.2)或类型为std :: nullptr_t的prvalue.空指针常量可以转换为指针类型; 结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开.