Использование boost::intrusive_ptr с вложенными классами

В частности, мне нужно объявить (насколько я понимаю) intrusive_ptr_{add_ref,release} друзьями моего ссылочного класса:

#include <boost/intrusive_ptr.hpp>
using boost::intrusive_ptr;

class Outer {
public:

    //user-exposed interface goes here

protected:
    class Inner {
    public:
        Inner():refct(0){}
        virtual ~Inner(){}

        //machinery goes here

        size_t refct;
    };

    friend void boost::intrusive_ptr_release(Inner *p);
    friend void boost::intrusive_ptr_add_ref(Inner *p);

    intrusive_ptr<Inner> handle;

};

namespace boost {

    void intrusive_ptr_release(Outer::Inner *p){
        if ((p->refct -= 1) <= 0){
            delete p;
        }
    }

    void intrusive_ptr_add_ref(Outer::Inner *p){
        p->refct++;
    }

};

У меня возникли проблемы с поиском правильного синтаксиса для компиляции и сохранения доступа, который я хочу. Моя главная проблема заключается в том, что gcc, похоже, расстроен тем, что «boost::intrusive_ptr_release(Outer::Inner *p) должен был быть объявлен в boost пространства имен».

Из этого примера я вижу, что хелперы intrusive_ptr предварительно объявлены внутри пространства имен boost, но я не могу объявить их вперед, потому что, насколько я понимаю, вложенные классы (т.е. "внутренние", на которые ссылаются эти функции) могут только быть предварительно объявлены внутри их внешних классов, и здесь также должно быть объявление друга.

О великие гуру С++, как правильно с этим справиться?


person trbabb    schedule 16.08.2011    source источник


Ответы (1)


Вам не нужно помещать их в namespace boost, вы можете поместить их в то же пространство имен, что и ваше class Outer, и они будут найдены с помощью поиска, зависящего от аргумента.

Каждый новый экземпляр intrusive_ptr увеличивает счетчик ссылок, используя неквалифицированный вызов функции intrusive_ptr_add_ref, передавая ей указатель в качестве аргумента.

person Yakov Galka    schedule 16.08.2011
comment
Ты прав; это работает. В одном из документов, которые я читал, прямо говорилось, что функции друзей должны находиться в пространстве имен boost (что поддерживается примером, на который я ссылался), поэтому я просто принял это как должное. Не знаю, почему я не попробовал это раньше. Спасибо! - person trbabb; 16.08.2011
comment
Ключевым словом здесь является поиск, зависящий от аргумента (обычно называемый поиском Кенига или просто ADL). Погуглите, стоит понять, почему такая фича есть в C++ и как она работает. - person Kos; 16.08.2011