为什么将const类型的智能指针强制转换为类型的智能指针有效?



知道为什么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中的错误列表窗口只将其截断到第一行,并丢失了基本信息。您应该查看构建输出,以获得完整的错误消息。

最新更新