2012-01-06 9 views
3

Это не компилируется,Что здесь происходит?

#include <boost/intrusive_ptr.hpp> 

class X 
{ 
public: 
void intrusive_ptr_add_ref(X* blah) 
{ 
} 

void intrusive_ptr_release(X * blah) 
{ 
} 

}; 



int main() 
{ 
    boost::intrusive_ptr<X> ex(new X); 
} 

Но это делает:

#include <boost/intrusive_ptr.hpp> 

class X 
{ 
public: 
    friend void intrusive_ptr_add_ref(X* blah) 
    { 
    } 

    friend void intrusive_ptr_release(X * blah) 
    { 
    } 

}; 



int main() 
{ 
    boost::intrusive_ptr<X> ex(new X); 
} 

и это:

#include <boost/intrusive_ptr.hpp> 

    class X 
    { 
    public: 


    }; 


    void intrusive_ptr_add_ref(X* blah) 
     { 
     } 

     void intrusive_ptr_release(X * blah) 
     { 
     } 

int main() 
{ 
    boost::intrusive_ptr<X> ex(new X); 
} 

Я предполагаю, что это что-то делать с SFINAE (который я гаванью» t пока что потрудился понять)? Определяет ли определитель друга определенную функцию как свободную функцию в закрытом пространстве имен?

редактировать

Кто лишил их должности, функции-члены, не друг, как add_ref и release (эти специфические функции-члены не упоминаются в documention ...) сделал решить эту проблему. Что происходит с вложенным определением с помощью классификатора friend?

+0

и какая ошибка вы получаете? –

+0

Что касается редактирования: функции, которые вы определили с помощью определителя друга, не являются функциями-членами, они являются свободными функциями. Тот факт, что они определены в теле класса, не делает их функциями-членами (я согласен, что это может ввести в заблуждение). –

+0

Что касается использования функций 'add_ref' и' release' вместо бесплатных функций, следует отметить, что это явно не указано в документации Boost (или, по крайней мере, мне ее не удалось найти). –

ответ

7

Из документации boost::intrusive_ptr:

Каждый новый экземпляр intrusive_ptr увеличивает счетчик ссылок с помощью неквалифицированного вызова функции intrusive_ptr_add_ref, передавая ему указатель в качестве аргумента. Аналогично, когда intrusive_ptr уничтожается, он вызывает intrusive_ptr_release; эта функция отвечает за уничтожение объекта, когда его счетчик ссылок падает до нуля. Ожидается, что пользователь предоставит подходящие определения этих двух функций. В компиляторах, поддерживающих зависящий от аргументов поиск, intrusive_ptr_add_ref и intrusive_ptr_release должны быть определены в пространстве имен, соответствующем их параметру; в противном случае, определения должны идти в boost пространства имен.

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

Edit: На ваш вопрос о вложенных определений с friend классификаторе: friend функции определяются как не memberfunctions, так friend void intrusive_ptr_add_ref(X* blah) будет называться intrusive_ptr_add_ref(my_x_ptr) вместо как my_x_ptr->intrusive_ptr_add_ref().

Смежные вопросы