使用类的 boost::intrusive_ptr 构造函数存在歧义「这个」指针

发布于 2024-08-18 14:21:58 字数 2088 浏览 2 评论 0原文

有问题的代码:

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();
}

GCC (4.4.1) with boost 1.41 在实例化第一个(非常量)版本的 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 当然不是。然而,最终的候选者是完美匹配的(布尔参数是可选的)。

有人愿意告诉我问题是什么吗?

编辑+答案:我终于意识到,在

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

this中指的是SharedObject,而Pointer typedef是SomeClass。 (这几乎就是巴特沃斯立即指出的)。

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

因为我知道 this 实际上是继承自 SharedObject 的 SomeClass,所以 static_cast 使模板类得以循环。

The offending code:

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);
  }
  ...

and used like 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();
}

GCC (4.4.1) with boost 1.41 gives this error upon instatiating the first (non-const) version of 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>

To my less than arcane skills in C++, I can't see why there is any ambiguity at all. The two canditates at lines 188 and 94 takes an existing intrusive_ptr rvalue reference, which SharedObject::this certainly is not. The final candidate however is a perfect match (the bool argument is optional).

Anyone care to enlighten me as to what the problem is?

EDIT+answer: I finally realized that in

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

this refers to SharedObject while the Pointer typedef is SomeClass. (Which is pretty much what Butterworth pointed out right away).

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

Since I know this to really be SomeClass, inheriting from SharedObject, a static_cast makes the template class go 'round.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吲‖鸣 2024-08-25 14:21:58

当你说:

typedef boost::intrusive_ptr<T> Pointer;

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

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

return Pointer(this); //Ambiguous call here

根据错误消息,这是一个 SharedObject ,但是我认为该指针被类型定义为 SomeClass 。

你的代码非常难以理解——无论你想做什么,都必须有一种更简单的方法。而且您似乎在基类中缺少虚拟析构函数(可能还有虚拟函数)。

When you say:

typedef boost::intrusive_ptr<T> Pointer;

you are declaring a type which is an intrusive pointer to an int (because T is an int at that point), when the template is instantiated in your code. Your SharedObject class is not an int, so you can't instantiate such an intrusive pointer using this.

Edit: OK, I misunderstood your code, I'll try again. At:

return Pointer(this); //Ambiguous call here

this is a SharedObject , as per the error messages, however the pointer is typedefed to a SomeClass I think.

Your code is incredibly hard to understand - whatever it is you are trying to do, there must be a simpler way. And you seem to be missing a virtual destructor (and maybe a virtual function) in the base class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文