任何想法为什么a1 = a2不起作用,但a2 = a1有效。智能指针模板中必须有一个执行转换的功能吗?是哪一个?
#include "stdafx.h"
#include<memory>
class TestClass
{
public:
int a ;
};
typedef std::shared_ptr<TestClass> TestSP;
typedef std::shared_ptr<const TestClass> TestConstSP;
int _tmain(int argc, _TCHAR* argv[])
{
TestSP a1 = TestSP();
TestConstSP a2 = TestConstSP();
//a1 =a2; //error C2440: '<function-style-cast>' : cannot convert from 'const std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty>'
a2=a1;
return 0;
}
答案 0 :(得分:0)
这是由const
的使用造成的。如果您有一个const
指针&#39; const_ptr
&#39;和一个非const
指针&#39; non_const_ptr
&#39;,可以这样做:
const_ptr = non_const_ptr; // const_ptr doesn't allow modifying the pointed value, while non_const_ptr does.
但禁止这样做:
non_const_ptr = const_ptr; // const_ptr is `const`. Allowing non_const_ptr to modify the pointed value would'n respect the `const` contract.
以下内容可行:
non_const_ptr = (type *) const_ptr; // You have the right to do that as you explicitely break the contract.
// The programmer is the boss. This is a bit ugly though.
完全相同的逻辑适用于您的示例。
答案 1 :(得分:0)
这是以一种有趣的方式指定的,看起来MSVC在这里实现了标准。赋值本身在§20.8.2.2.3[util.smartptr.shared.assign] / p1-3中指定:
shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
效果:相当于
shared_ptr(r).swap(*this)
。返回:
*this
。[注意:临时对象构造和销毁导致的使用计数更新不是 可观察到的副作用,因此实施可能会影响效果(和隐含的保证) 不同的手段,没有创造一个临时的。
<example omitted>
]
相关构造函数在§20.8.2.2.1[util.smartptr.shared.const] / p17-19中指定:
shared_ptr(const shared_ptr& r) noexcept; template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
需要:第二个构造函数不应参与重载决策,除非
Y*
可隐式转换为T*
。效果:如果
r
为空,则构造一个空的shared_ptr
对象;否则,构造一个共享所有权的shared_ptr
对象r
。后置条件:
get() == r.get() && use_count() == r.use_count()
。
由于const TestClass *
不能隐式转换为TestClass *
,因此模板化构造函数不参与重载解析,因为没有匹配的构造函数而导致shared_ptr(r)
格式错误。
修改:我看到了混乱。 VS2012在报告编译器错误消息时设计得很差。编译器发出的完整错误消息是:
error C2440: '<function-style-cast>' : cannot convert from 'const std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty>'
with
[
_Ty=const TestClass
]
and
[
_Ty=TestClass
]
重要的是,错误输出中的两个_Ty
指的是不同的类型。但是,VS2012中的“错误列表”窗口仅将其截断为第一行,并丢失该重要信息。您应该查看完整错误消息的构建输出。