这里发生了什么?

时间:2012-01-06 17:31:22

标签: c++ smart-pointers boost-smart-ptr

这不编译,

#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_refrelease(这些特定成员函数未在documention ...中提及)确实解决了问题。使用friend限定符的嵌套定义会发生什么?

1 个答案:

答案 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_refintrusive_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()