这不编译,
#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有关(我还没有想过要理解)? friend限定符是否将已定义的函数作为自由函数放在封闭的命名空间中?
修改
无论谁删除了他们的帖子,成员函数非朋友add_ref
和release
(这些特定成员函数未在documention ...中提及)确实解决了问题。使用friend
限定符的嵌套定义会发生什么?
答案 0 :(得分:7)
来自boost::intrusive_ptr
的文档:
每个新的intrusive_ptr实例都使用对函数intrusive_ptr_add_ref的非限定调用来递增引用计数,并将指针作为参数传递给它。同样,当一个intrusive_ptr被销毁时,它会调用intrusive_ptr_release;当函数的引用计数降为零时,此函数负责销毁对象。期望用户提供这两个功能的合适定义。在支持依赖于参数的查找的编译器上,应该在与其参数对应的命名空间中定义intrusive_ptr_add_ref和intrusive_ptr_release;否则,定义需要进入名称空间提升。
这意味着intrusive_ptr_add_ref
和intrusive_ptr_release
不应该是成员函数,而是自由函数(朋友函数就是这样)。此外,它们被无限制地调用,因此它们应该位于全局命名空间或ADL找到的某个位置。
修改:关于使用friend
限定符的嵌套定义的问题:
friend
个函数被定义为非成员函数,因此friend void intrusive_ptr_add_ref(X* blah)
将被称为intrusive_ptr_add_ref(my_x_ptr)
,而不是my_x_ptr->intrusive_ptr_add_ref()
。