1

我正在编写的共享指针类中有一个方法。

template<class T>
template<class Y>
shared_ptr<T> &shared_ptr<T>::operator=(/*const*/ shared_ptr<Y> &r)
{
  shared_ptr<T>(r).swap(*this);
  return *this;
}

以这种方式使用时

class Foo
{
};

class Bar : public Foo
{
};

int main(int /*argc*/, char * /*argv*/[]) {
  shared_ptr<Foo> giPtr(new Foo(1));
  shared_ptr<Bar> giPtr2;
  giPtr2 = glext::dynamic_pointer_cast<Foo>(giPtr);
} 

在 MSVC 中生成以下错误:

1>c:\users\mehoggan\documents\github\x86-applications\glextensions\smart_ptrs\shared_ptr\shared_ptr.inl(53): error C2440: '<function-style-cast>' : cannot convert from 'glext::shared_ptr<T>' to 'glext::shared_ptr<T>'
1>          with
1>          [
1>              T=Foo
1>          ]
1>          and
1>          [
1>              T=Bar
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous
1>          main.cpp(28) : see reference to function template instantiation 'glext::shared_ptr<T> &glext::shared_ptr<T>::operator =<Foo>(glext::shared_ptr<Foo> &)' being compiled
1>          with
1>          [
1>              T=Bar
1>          ]

构造函数

template<class T>
  shared_ptr<T>::shared_ptr() : 
    _px(0), 
    _pn()
  {}

  template<class T>
  template<class Y>
  shared_ptr<T>::shared_ptr(Y * p) : 
    _px(p), 
    _pn()
  {
    internal::shared_pointer_construct(this, p, _pn);
  }

  // TODO: Create shared ptr from weak pointer

  template<class T>
  shared_ptr<T>::shared_ptr(const shared_ptr &r) :
    _px(r._px),
    _pn(r._pn)
  {}

  template<class T>
  template<class Y>
  shared_ptr<T>::shared_ptr(const shared_ptr<Y> &r, element_type *p) :
    _px(p), 
    _pn(r._pn)
  {}

  template<class T>
  shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr<T> &r)
  {
    shared_ptr<T>(r).swap(*this);
    return *this;
  }

交换

template<class T>
void shared_ptr<T>::swap(shared_ptr<T> &other)
{
  std::swap(_px, other._px);
  _pn.swap(other._pn);
}
4

1 回答 1

3

这个问题经常出现在 MSVC 中。

您可以尝试使用“注入”名称,而不是返回类型的模板 ID:

template<class T>
template<class Y>
shared_ptr<T> &shared_ptr<T>::operator=(/*const*/ shared_ptr<Y> &r)
{
  shared_ptr(r).swap(*this); // note: no <T> there
  return *this;
}

我不太确定,但你可能很幸运地在课堂上定义了这个:

template<class T> class shared_ptr
{
    template<class Y>
    shared_ptr& operator=(shared_ptr<Y> &r)
    {
      shared_ptr(r).swap(*this); // note: no <T> there
      return *this;
    }
    // ...

我在这里猜测了一下,但我认为该类在定义方法体时可能“看起来”不完整。我不认为这应该是一个问题,但是 MSVC 两阶段查找1是出了名的......麻烦。


1(基本上是模板实例化机制)

于 2013-08-05T00:48:45.323 回答