知道为什么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;
}
这是由于const
的使用。如果你有一个const
指针' const_ptr
'和一个非const
指针' non_const_ptr
',这是可以做的:
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.
同样的逻辑也适用于你的例子
这是以一种有趣的方式指定的,看起来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*
,否则第二个构造函数不得参与重载解析。Effects:如果
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
s引用了不同的类型。然而,VS2012中的错误列表窗口只将其截断到第一行,并丢失了基本信息。您应该查看构建输出,以获得完整的错误消息。