这里发生了什么事情?(关于IT技术的问题)

4

这个无法编译,

#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有关(我还没有去理解)。友元限定符是否将定义的函数作为封闭命名空间中的自由函数? 编辑 删除他们的帖子的人,非友元成员函数如add_refrelease(这些特定成员函数在文档中没有提到...)解决了问题。带有friend限定符的嵌套定义会发生什么?

你遇到了什么错误? - Yochai Timmer
关于修改:您使用 friend 修饰符定义的函数不是成员函数,而是自由函数。它们在类体中定义并不意味着它们是成员函数(我同意这可能会误导)。 - Luc Touraille
关于使用 add_refrelease 成员函数而不是自由函数,应该注意到 Boost 文档中没有明确说明(或者至少我没有找到)。 - Luc Touraille
1个回答

7
boost::intrusive_ptr的文档中可以看到:
每个新的intrusive_ptr实例都会通过对函数intrusive_ptr_add_ref进行非限定调用来增加引用计数,将指针作为参数传递给它。同样,当一个intrusive_ptr被销毁时,它调用intrusive_ptr_release;当对象的引用计数降至零时,这个函数负责销毁对象。用户应该提供这两个函数的合适定义。在支持参数相关查找的编译器上,intrusive_ptr_add_refintrusive_ptr_release应该在与其参数对应的命名空间中定义;否则,这些定义需要放在boost命名空间中。
这意味着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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接