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

时间:2014-07-23 14:29:35

标签: c++ templates type-conversion smart-pointers

任何想法为什么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;
}

2 个答案:

答案 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中的“错误列表”窗口仅将其截断为第一行,并丢失该重要信息。您应该查看完整错误消息的构建输出。