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と関係があると思います(私はまだ理解していません)?フレンド修飾子は、定義された関数を囲まれた名前空間の自由関数として配置しますか?

編集

投稿を削除した人は誰でも、メンバー関数は友人ではなくadd_refrelease(これらの特定のメンバー関数はドキュメントには記載されていません...) 問題を解決しました。friend修飾子でネストされた定義はどうなりますか?

4

1 に答える 1

7

のドキュメントからboost::intrusive_ptr:

すべての新しい intrusive_ptr インスタンスは、関数 intrusive_ptr_add_ref への非修飾呼び出しを使用して参照カウントをインクリメントし、引数としてポインターを渡します。同様に、intrusive_ptr が破棄されると、intrusive_ptr_release が呼び出されます。この関数は、参照カウントがゼロになったときにオブジェクトを破棄する責任があります。ユーザーは、これら 2 つの関数の適切な定義を提供することが期待されます。引数依存のルックアップをサポートするコンパイラでは、 intrusive_ptr_add_ref と intrusive_ptr_release は、それらのパラメーターに対応する名前空間で定義する必要があります。それ以外の場合、定義は名前空間ブーストに入る必要があります。

これは、intrusive_ptr_add_refandintrusive_ptr_releaseがメンバー関数ではなく、フリー関数であることを意味します (フレンド関数はそのように動作します)。さらに、それらは修飾なしで呼び出されるため、グローバル名前空間または ADL によって検出された場所にある必要があります。

friend編集:修飾子 を使用したネストされた定義に関する質問に対して:friend関数は非メンバー関数として定義されているため、 asの代わりに asfriend void intrusive_ptr_add_ref(X* blah)が呼び出されます。intrusive_ptr_add_ref(my_x_ptr)my_x_ptr->intrusive_ptr_add_ref()

于 2012-01-06T17:35:46.203 に答える