为什么不将shared_ptr <A>隐式转换为shared_ptr <A const>?

bit*_*ask 10 c++ const-correctness shared-ptr c++11

我试图向const一些新代码介绍一些正确性(实际上是函数范例),并发现我无法将std::shared_ptr<A>一个函数传递给期望的函数std::shared_ptr<A const>.请注意,我不想抛弃 const而是引入它,这对于原始指针是合法的.

有办法解决这个问题吗?我没有找到成员函数来执行此操作.


g ++ 4.6.1发出的确切错误是:

error: no matching function for call to ‘foo(std::shared_ptr<A>)’
note: candidate is:
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>)
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 10

您的案例中的问题不是来自/可能的转换std::shared_ptr,而是与类型推断如何适用于模板函数更相关.

当编译器尝试将函数调用与模板匹配时,它只接受完全匹配,即根本没有类型转换.在这种情况下,你的功能需要std::shared_ptr<const T>,调用者有一个std::shared_ptr<U>地方U是不是const.由于匹配不准确,它将丢弃模板并选择下一个重载候选项.

简单的解决方法是:完全避免类型推断并提供模板参数:

std::shared_ptr<A> p;
foo<A>(p);             // will use the templated shared_ptr conversion
Run Code Online (Sandbox Code Playgroud)

或者自己执行转换:

foo(std::shared_ptr<const A>(p));
Run Code Online (Sandbox Code Playgroud)

  • @David,`foo(std :: shared_ptr <const A>(p));`保留引用计数? (4认同)
  • @bitmask号`const_cast`用于*删除*限定符.添加它们只需要进行隐式转换 - "static_cast"是将转换记录为显式的适当强制转换.如果在代码更改期间出于任何原因更改目标和源类型以使源类型为cv-qualified,但目标类型不是,则`const_cast`不会发出警告. (3认同)
  • @MarkIngram:*以某种方式保留*.由于您正在创建共享指针的*副本*,因此将增加该值以保持一致性.`std :: shared_ptr`支持不同类型的别名,包括将共享指针保存到由共享指针管理的对象的成员中,其中指针和指向成员变量的指针将共享计数和删除(即最后一个)一个人去清理) (2认同)
  • @LucDanton:鉴于类型必须至少显式命名一次,我发现`foo <int>(p)`比`foo(std :: static_pointer <int const>(p)更清洁(和更短) )`,反过来比`foo(std :: static_pointer_cast <int const>(p))`更好.如果不是出于任何其他原因,则输入的内容较少,字符数较少. (2认同)