boost :: intrusive_ptr构造函数歧义使用类''this'指针

时间:2010-01-22 10:14:22

标签: c++ templates boost ambiguity

违规代码:

template<typename T>
class SharedObject {
 public:
  typedef boost::intrusive_ptr<T> Pointer;
  typedef boost::intrusive_ptr<T const> ConstPointer;
  inline Pointer GetPointer() {
    return Pointer(this); //Ambiguous call here
  }
  inline ConstPointer GetPointer() const {
    return ConstPointer(this);
  }
  ...

并像这样使用:

template <typename T>
class SomeClass: public SharedObject<SomeClass<T> > {
 public:
  static inline boost::intrusive_ptr<SomeClass<T> > Create() {
    return (new SomeClass)->GetPointer();
  }
};

int main()
{
  auto v = SomeClass<int>::Create();
}
带有boost 1.41的GCC(4.4.1)在设置第一个(非常量)版本的GetPointer()时出现此错误:

error: call of overloaded ‘intrusive_ptr SharedObject<SomeClass<int> >* const)’ is ambiguous
boost/smart_ptr/intrusive_ptr.hpp:118: note: candidates are: boost::intrusive_ptr<T>::intrusive_ptr(boost::intrusive_ptr<T>&&) [with T = SomeClass<int>] <near match>
boost/smart_ptr/intrusive_ptr.hpp:94:  note:                 boost::intrusive_ptr<T>::intrusive_ptr(const boost::intrusive_ptr<T>&) [with T = SomeClass<int>] <near match>
boost/smart_ptr/intrusive_ptr.hpp:70:  note:                 boost::intrusive_ptr<T>::intrusive_ptr(T*, bool) [with T = SomeClass<int>] <near match>

对于我在C ++中不太神秘的技能,我无法理解为什么会有任何歧义。第188行和第94行的两个候选者采用现有的intrusive_ptr右值引用,SharedObject::this当然不是。然而,最终的候选人是一个完美的匹配(bool参数是可选的)。

任何人都想关心问题是什么?

编辑+回答:我终于意识到了

  inline Pointer GetPointer() {
    return Pointer(this); //Ambiguous call here
  }

this引用SharedObject,而Pointer typedef是SomeClass。 (这正是Butterworth马上指出的)。

  inline Pointer GetPointer() {
    return Pointer(static_cast<C*>(this));
  }

因为我知道this真的是SomeClass,继承自SharedObject,所以static_cast使模板类变为'round。

1 个答案:

答案 0 :(得分:2)

当你说:

typedef boost::intrusive_ptr<T> Pointer;

当您在代码中实例化模板时,您声明的类型是指向int的入侵指针(因为此时Tint)。您的SharedObject类不是int,因此您无法使用this实例化此类侵入式指针。

编辑:好的,我误解了你的代码,我会再试一次。于:

return Pointer(this); //Ambiguous call here

这是一个SharedObject,根据错误消息,但是我认为指针是somedefed到SomeClass。

您的代码难以理解 - 无论您想要做什么,都必须有一种更简单的方法。而且你似乎在基类中缺少一个虚拟析构函数(也许是一个虚函数)。