鉴于以下计划:
#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>() );
}
我收到以下错误(来自g ++ 4.7.2):
noX.cc: In instantiation of ‘SharedPtr<T>::SharedPtr(const SharedPtr<U>&) [with U = const D; T = D]’:
noX.cc|33 col 37| required from ‘Handle<Derived> Handle<T>::DynamicCast() const [with Derived = D; T = B]’
noX.cc|45 col 37| required from here
noX.cc|13 col 88| error: no matching function for call to ‘std::shared_ptr<D>::shared_ptr(const SharedPtr<const D>&)’
noX.cc|13 col 88| note: candidates are:
以及一长串候选人。微软(MSVC 11)给出了 一个类似的消息,所以我假设错误在我的代码中,并且 不是编译器错误。
显然,我不希望能够转换
a SharedPtr<D const>
到SharedPtr<D>
(或
一个std::shared_ptr<D const>
到std::shared_ptr<D>
,这是
微软抱怨的东西)。但是在哪里呢
SharedPtr<D>
首先来自哪里?我什么也看不见
在上面的代码中应该创建任何智能指针的东西
任何类型为非const。
答案 0 :(得分:4)
这个构造函数:
Handle( SharedPtr<T> const& src ) : Base( src ) {}
依赖于从SharedPtr<T>
到SharedPtr<T const>
的隐式转换(即Base
)。但是在这里:
return Handle<Derived>( tmp );
您需要SharedPtr<T const>
- &gt; Handle<T>
转换,但唯一可能的候选者是构造函数SharedPtr<T>
。一种解决方案是将其更改为:
Handle(Base const& src ) : Base( src ) {}
如果需要,'移动'隐式转换给调用者。
答案 1 :(得分:3)
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 );
}
您返回Handle
,其中T的类型为Derived
而不是常量。 SharedPtr<T>
中的T虽然是Derived const
类型。
答案 2 :(得分:3)
乍一看,SharedPtr<Derived>
Handle( SharedPtr<T> const& src )
来电隐式创建return Handle<Derived>( tmp );
对象