неоднозначность конструктора boost :: intrusive_ptr с использованием указателя класса '' this ' - PullRequest
1 голос
/ 22 января 2010

Код обидчика:

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) с бустом 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 rvalue, которой SharedObject::this, безусловно, не является. Последний кандидат, однако, идеально подходит (аргумент bool не обязателен).

Кто-нибудь хочет просветить меня, в чем проблема?

РЕДАКТИРОВАТЬ + ответить : я наконец понял, что в

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

this относится к SharedObject, в то время как typedef типа Pointer - SomeClass. (Который в значительной степени то, на что сразу указал Баттерворт).

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

Поскольку я знаю, что this действительно является SomeClass, унаследованным от SharedObject, static_cast заставляет класс шаблона вращаться.

1 Ответ

2 голосов
/ 22 января 2010

Когда вы говорите:

typedef boost::intrusive_ptr<T> Pointer;

вы объявляете тип, который является навязчивым указателем на int (потому что T - это int в этот момент), когда шаблон создается в вашем коде. Ваш класс SharedObject не является int, поэтому вы не можете создать такой навязчивый указатель, используя this.

Редактировать: ОК, я неправильно понял ваш код, попробую еще раз. В:

return Pointer(this); //Ambiguous call here

это SharedObject, согласно сообщениям об ошибках, однако, я думаю, указатель определен на SomeClass.

Ваш код невероятно труден для понимания - что бы вы ни пытались сделать, должен быть более простой способ. Кажется, вам не хватает виртуального деструктора (и, возможно, виртуальной функции) в базовом классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...