2014-07-23 73 views
0

任何想法为什么a1 = a2不起作用,但a2 = a1起作用。智能指针模板中必须有一个用于转换的功能?哪一个?为什么将一个智能指针的const类型转换为类型作品的智能指针

#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

[本列表中的第二个](http://en.cppreference.com/w/cpp/memory/shared_ptr/operator%3D)(仍然标为#1)。 –

回答

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. 

完全相同的逻辑适用于您的示例。

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对象;否则,构建与 r共享所有权的shared_ptr对象。

后续条件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 IN误差输出指的是不同类型。然而,VS2012中的错误列表窗口仅将其截断到第一行,并丢失了重要信息。您应该查看完整的错误消息的构建输出。

+0

这解释了const std :: shared_ptr 和std :: shared_ptr 之间的转换,但它是std :: shared_ptr 与const std :: shared_ptr相同 KKKoo0

+0

不,转换是在'shared_ptr ''和'shared_ptr '。顶级常量(如'const std :: shared_ptr ')对于转换无关紧要。 VS2013给了我错误'错误C2440:'':不能从'const std :: shared_ptr '转换为'std :: shared_ptr''' –