C++ 为什么';t共享\u ptr<;A>;隐式转换为共享\u ptr<;常数>;?

C++ 为什么';t共享\u ptr<;A>;隐式转换为共享\u ptr<;常数>;?,c++,c++11,shared-ptr,const-correctness,C++,C++11,Shared Ptr,Const Correctness,我试图在一些新代码中引入一些const正确性(实际上是函数范例),发现我无法将std::shared_ptr传递给需要std::shared_ptr的函数。注意,我不想抛弃constness,而是引入它,这对于原始指针是合法的 有什么办法可以解决这个问题吗?我没有找到一个成员函数来执行此操作 g++4.6.1发出的精确错误为: error: no matching function for call to ‘foo(std::shared_ptr<A>)’ note: candid

我试图在一些新代码中引入一些
const
正确性(实际上是函数范例),发现我无法将
std::shared_ptr
传递给需要
std::shared_ptr
的函数。注意,我不想抛弃constness,而是引入它,这对于原始指针是合法的

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


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>)
错误:调用“foo(std::shared_ptr)”时没有匹配的函数
注:候选人为:
注:模板std::shared\u ptr foo(std::shared\u ptr)

您案例中的问题不是从不同的
std::shared\u ptr
到不同的
std::shared\u ptr的可能转换,而是与模板函数的类型推断工作方式有关

当编译器尝试将函数调用与模板匹配时,它将只接受精确的匹配,即根本不接受类型转换。在这种情况下,函数采用
std::shared_ptr
,调用方采用
std::shared_ptr
,其中
U
不是
const
。由于匹配不精确,它将丢弃模板并选择下一个重载候选项

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

std::shared_ptr<A> p;
foo<A>(p);             // will use the templated shared_ptr conversion
std::shared\u ptr p;
foo(p);//将使用模板化的共享ptr转换
或者自己执行转换:

foo(std::shared_ptr<const A>(p));
foo(std::shared_ptr(p));

@Xeo,因为我们没有删除cv限定符。@David,是
foo(std::shared_ptr(p))保留引用计数?@bitmask No.
const_cast
用于删除限定符。添加它们只需要隐式转换--
static\u cast
是将转换记录为显式的合适转换。如果在代码更改过程中,由于任何原因,目标和源类型被更改,以致源类型是cv限定的,而目标类型不是cv限定的,则
const\u cast
不会发出警告。@MarkIngram:以某种方式保留。由于您正在创建共享指针的副本,因此该值将递增以保持一致性
std::shared_ptr
支持不同类型的别名,包括将共享指针保存到由共享指针管理的对象的成员中,其中指针和指向成员变量的指针将共享一个计数和删除器(即最后一个将被清除)@LucDanton:考虑到类型必须至少显式命名一次,我发现
foo(p)
foo(std::static\u pointer(p))
更干净(更短),而这又比
foo(std::static\u pointer\u cast(p))
更好。如果不是因为任何其他原因,输入的内容会减少,读取的字符也会减少。