从int到shared_ptr的隐式转换 [英] Implicit conversion from int to shared_ptr

查看:517
本文介绍了从int到shared_ptr的隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

  #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); //不为任何其他int!= 0工作,感谢@Rupesh
// call_f(f,0); //错误,无法将int转换为shared_ptr
}

c $ c> main(),则将整数 0 转换为 std :: shared_ptr< int& code>并且调用 f(0)成功没有任何问题。但是,使用模板调用函数使事物不同。第二行将不再编译,错误是

 错误:无法将'p'从'int'转换为'std: :shared_ptr< int>'

我的问题是:


$ b b


  1. 为什么第一次调用成功,第二次调用不成功?

  2. 我不明白如何从 int f(0),因为它看起来像 std :: shared_ptr,正在执行> std :: shared_ptr 只有显式构造函数。

PS:此示例的一个变体出现在Scott Meyers的 Effective Modern C ++

解决方案

std :: shared_ptr 有一个构造函数,它使用 std :: nullptr_t ,literal 0 是一个空指针常量,可以从草稿C ++标准节 4.10转换为 std :: nullptr_t [conv.ptr] 强调我的未来):


空指针常量是一个整数常量表达式(5.19),整数类型的prvalue值为零或类型为
std :: nullptr_t
的prvalue。空指针常量可以转换为
指针类型;结果是该类型的空指针值,并且
可以与对象指针或函数
指针类型的每个其他值区分开。这种转换称为空指针转换。
同一类型的两个空指针值应比较相等。
将空指针常量转换为cv限定的
类型的指针是单次转换,而不是指针
转换的序列,后面跟着转换(4.4)。 null
整数类型的指针常量可以转换为
类型std :: nullptr_t
的prvalue。 [注意:生成的prvalue不是一个空的
指针值。 -end note]


您的第二种情况 p



如果TC的值为零,则不再是一个空指针常量,因此不适合同样的情况。指出措辞已更改为 DR 903 ,它需要一个值为零的整数字面值,而不是一个值为零的整数常量表达式:


空指针常数是值为
zero 的整数常数(2.14.2)或类型为std :: nullptr_t的prvalue。空指针常量
可以转换为指针类型;结果是该类型的空指针
值,并且可以与
对象指针或函数指针类型的每个其他值区分开。



Consider the code below:

#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
}

In the first line in main(), the integer 0 is converted to a std::shared_ptr<int> and the call f(0) succeeds without any problem. However, using a template to call the function make matter different. Second line will not compile anymore, the error being

error: could not convert 'p' from 'int' to 'std::shared_ptr<int>'

My questions are:

  1. Why does the first call succeed and the second doesn't? Is there anything I'm missing here?
  2. I don't understand also how the conversion from int to std::shared_ptr is being performed in the call f(0), as it looks like std::shared_ptr has only explicit constructors.

PS: A variant of this example appears in Scott Meyers' Effective Modern C++ Item 8, as a way of protecting such calls with nullptr.

解决方案

std::shared_ptr has a constructor that takes std::nullptr_t, literal 0 is a null pointer constant that is convertiable to std::nullptr_t from the draft C++ standard section 4.10 [conv.ptr] (emphasis mine going forward):

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 ]

in your second case p is being deduced as type int which although has the value zero is no longer a null pointer constant and so does not fit the same case.

As T.C. points out the wording was changed with DR 903 which requires an integer literal with value zero as opposed to an integral constant expression which evaluates to zero:

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.

这篇关于从int到shared_ptr的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆