C++ std::shared_ptr losing const的实例化类型
鉴于以下计划:C++ std::shared_ptr losing const的实例化类型,c++,c++11,C++,C++11,鉴于以下计划: #include <memory> template <typename T> class SharedPtr : public std::shared_ptr<T> { typedef std::shared_ptr<T> Impl; template<typename U> friend class SharedPtr; SharedPtr( Impl const& other )
#include <memory>
template <typename T>
class SharedPtr : public std::shared_ptr<T>
{
typedef std::shared_ptr<T> Impl;
template<typename U> friend class SharedPtr;
SharedPtr( Impl const& other ) : Impl( other ) {}
public:
SharedPtr( T* newed_ptr ) : Impl( newed_ptr ) {}
SharedPtr( SharedPtr const& other ) throw() : Impl( other ) {}
template <typename U> SharedPtr( SharedPtr<U> const& other ) throw() : Impl( other ) {}
template <typename U> SharedPtr<U> DynamicCast() const throw()
{
return SharedPtr<U>( std::dynamic_pointer_cast<U>( *this ) );
}
};
template<typename T> class Handle : public SharedPtr<T const>
{
typedef SharedPtr<T const> Base;
template <typename U> friend class Handle;
public:
explicit Handle( T const* pObject = 0 ) : Base( pObject ) {}
Handle( SharedPtr<T> const& src ) : Base( src ) {}
template <typename Derived>
Handle( Handle<Derived> const& other ) : Base( other ) {}
template <typename Derived>
Handle<Derived> DynamicCast() const throw() {
SharedPtr<Derived const> tmp = this->Base::template DynamicCast<Derived const>();
return Handle<Derived>( tmp );
}
};
class B { public: virtual ~B() {} };
class D : public B{};
void
testit()
{
Handle<D> p( new D );
Handle<B> p1( p );
Handle<D> p2( p1.DynamicCast<D>() );
}
#包括
模板
类SharedPtr:public std::shared\u ptr
{
typedef std::共享\u ptr Impl;
模板好友类SharedPtr;
SharedPtr(Impl const&other):Impl(other){}
公众:
SharedPtr(T*newed_ptr):Impl(newed_ptr){}
SharedPtr(SharedPtr const&other)throw():Impl(other){}
模板SharedPtr(SharedPtr const&other)throw():Impl(other){}
模板SharedPtr DynamicCast()常量throw()
{
返回SharedPtr(std::dynamic_pointer_cast(*this));
}
};
模板类句柄:publicsharedptr
{
typedef-SharedPtr-Base;
模板好友类句柄;
公众:
显式句柄(T const*pObject=0):基(pObject){}
句柄(SharedPtr const&src):基(src){}
模板
句柄(句柄常量和其他):基(其他){}
模板
句柄DynamicCast()常量throw(){
SharedPtr tmp=this->Base::template DynamicCast();
返回手柄(tmp);
}
};
类B{public:virtual~B(){};
D类:公共B{};
无效的
testit()
{
手柄p(新的D);
手柄p1(p);
句柄p2(p1.DynamicCast());
}
我得到以下错误(来自g++4.7.2):
noX.cc:SharedPtr::SharedPtr(constsharedptr&)[with U=constd;T=D]的实例化:
noX.cc | 33 col 37 |必须来自“Handle Handle::DynamicCast()const[with-Derived=D;T=B]”
noX.cc | 45 col 37 |此处需要
noX.cc | 13 col 88 |错误:调用“std::shared_ptr::shared_ptr(const SharedPtr&)”时没有匹配函数
noX.cc | 13 col 88 |注:候选人包括:
还有一长串的候选人。微软(MSVC 11)提供
类似的消息,因此我假设错误在我的代码中,并且
不是编译器错误
很明显,我不希望能够转换
aSharedPtr
到aSharedPtr
(或
astd::shared_ptr
到astd::shared_ptr
,即
微软的抱怨)。但是这家公司在哪里
SharedPtr
首先来自哪里?我什么也看不见
上面代码中应该创建的任何智能指针
非常量的任何类型。模板类句柄:public SharedPtr
template<typename T> class Handle : public SharedPtr<T const>
{
Handle( SharedPtr<T> const& src ) : Base( src ) {}
Handle<Derived> DynamicCast() const throw() {
SharedPtr<Derived const> tmp = this->Base::template DynamicCast<Derived const>();
return Handle<Derived>( tmp );
}
{
句柄(SharedPtr const&src):基(src){}
句柄DynamicCast()常量throw(){
SharedPtr tmp=this->Base::template DynamicCast();
返回手柄(tmp);
}
您的返回是
句柄
其中T的类型为派生
而不包含常量。SharedPtr
中的T的类型为派生常量
。乍一看,似乎是为句柄(SharedPtr const&src)
调用返回句柄(tmp)隐式创建了SharedPtr
对象;
此构造函数:
Handle( SharedPtr<T> const& src ) : Base( src ) {}
您需要一个SharedPtr
->句柄
转换,尽管唯一可能的候选对象是采用SharedPtr
的构造函数。一个解决方案是将其更改为:
Handle(Base const& src ) : Base( src ) {}
如果需要,将隐式转换“移动”到调用者。很好。我将
SharedPtr
构造函数更改为Handle(SharedPtr const&src)
,示例代码现在可以编译了。(我必须看看这是否纠正了真实代码中的问题,但SharedPtr
显然是一个错误。@LucDanton是的。这就是错误。我只是没有找准位置。另一个问题是你?你想用这些类实现什么?只是好奇…@Dilip提供了一个安全的函数式界面。它们是部分历史条件,但在实际代码中,它们当然要复杂得多。尤其是模板类SharedPtr,具有部分专门化,因此
SharedPtr`的实际实现取决于指向类是否支持入侵引用计数(从长远来看,要摆脱无创参考计数,太危险了)。
return Handle<Derived>( tmp );
Handle(Base const& src ) : Base( src ) {}