0

boost::intrusive_ptrclass の参照カウントに使用したいので、 namespace で定義する必要があるおよび関数のフィールドとフレンド宣言x::Yを追加します。次に、それらの関数を記述します。このような:referencesreleaseadd_refboost

namespace x{


    class Y{
        long    references;
        friend void boost::intrusive_ptr_add_ref(x::Y * p);
        friend void boost::intrusive_ptr_release(x::Y * p);
    };
}

namespace boost
{
    void intrusive_ptr_add_ref(x::Y * p)
    {
        ++(p->references);
    }

    void intrusive_ptr_release(x::Y * p)
    {
        if (--(p->references) == 0)
            delete p;
    }
}

コードがコンパイルされず、次のエラーが表示されます。

test/test6.cpp:8:18: error: ‘boost’ has not been declared
test/test6.cpp:9:18: error: ‘boost’ has not been declared
test/test6.cpp: In function ‘void boost::intrusive_ptr_add_ref(x::Y*)’:
test/test6.cpp:7:11: error: ‘long int x::Y::references’ is private
test/test6.cpp:17:9: error: within this context
test/test6.cpp: In function ‘void boost::intrusive_ptr_release(x::Y*)’:
test/test6.cpp:7:11: error: ‘long int x::Y::references’ is private
test/test6.cpp:22:13: error: within this context

ブーストのドキュメントで説明されているようにすべてをやったと思っていましたが、何か間違ったことをしたようです。問題はどこだ?

4

6 に答える 6

3

エラーは、boostその名前空間の宣言の前に、クラス定義で名前空間を参照しているためです。namespace boostクラス定義の前に宣言することで修正できます。関数も宣言する必要があります。そのためには、クラスと名前空間も宣言する必要があります。

namespace x {class Y;}
namespace boost
{
    void intrusive_ptr_add_ref(x::Y * p);
    void intrusive_ptr_release(x::Y * p);
}

boostただし、関数を名前空間ではなく、クラスを含む名前空間 (つまり)に配置する方がよい場合がありますnamespace x。次にintrusive_ptr、引数に依存する名前のルックアップによって正しいバージョンを見つけます。これには、クラスの前に宣言する必要はありません。

于 2012-08-31T14:32:19.327 に答える
2

この特定の最小限のコードでは、何かが欠けているようです

namespace x { class Y; }
namespace boost {
        void intrusive_ptr_add_ref(x::Y * p);
        void intrusive_ptr_release(x::Y * p);
}

最初に。つまり、Y を前方宣言し、関数を宣言します。ただし、関数が属していない名前空間に関数を配置するためだけに、なぜこの苦痛を経験したいのでしょうか。

于 2012-08-31T14:32:44.880 に答える
1

それらを前方宣言する必要があります。

コンパイラが Argument Dependent Lookup をサポートしている場合は、関数intrusive_ptr_add_refintrusive_ptr_releaseを独自の名前空間に配置し、そこでも前方宣言する必要があります。

namespace x{
    void intrusive_ptr_add_ref(x::Y * p);

    void intrusive_ptr_release(x::Y * p);

    class Y{
        long    references;
        friend void boost::intrusive_ptr_add_ref(x::Y * p);
        friend void boost::intrusive_ptr_release(x::Y * p);
    };

    void intrusive_ptr_add_ref(x::Y * p)
    {
        ++(p->references);
    }

    void intrusive_ptr_release(x::Y * p)
    {
        if (--(p->references) == 0)
            delete p;
    }
}

編集: それらをブースト名前空間に配置したい場合は、クラスの前にこれら 2 つの関数宣言を含むブースト名前空間を前方宣言することで、代わりにそれを行うことができます。

于 2012-08-31T14:33:36.890 に答える
1

これらの関数は で定義できますnamespace x。しかし、で関数を宣言したい場合はnamespace boost、次のようなものを使用してください

#include <boost/intrusive_ptr.hpp>

namespace x
{
   class Y;
}

namespace boost
{
    void intrusive_ptr_add_ref(x::Y * p);
    /*{
        ++(p->references);
    }*/

    void intrusive_ptr_release(x::Y * p);
    /*{
        if (--(p->references) == 0)
            delete p;
    }*/
}

namespace x{

    class Y{
        long    references;
        friend void boost::intrusive_ptr_add_ref(x::Y * p);
        friend void boost::intrusive_ptr_release(x::Y * p);
    };
}

namespace boost
{
    void intrusive_ptr_add_ref(x::Y * p)
    {
        ++(p->references);
    }

    void intrusive_ptr_release(x::Y * p)
    {
        if (--(p->references) == 0)
            delete p;
    }
}

http://liveworkspace.org/code/99cb62380019ccb39993f0a9e656eff2

于 2012-08-31T14:34:12.297 に答える
0

クラスと同じ名前空間、つまりで定義すると機能intrusive_ptr_add_refします。intrusive_ptr_release::x::Y::x

于 2012-08-31T14:29:21.223 に答える
0

最初のエラーは、ブースト ヘッダーが含まれていないことを示しています。friend残りは、最初のエラーが宣言の解析エラーを引き起こすためです。

于 2012-08-31T14:32:35.020 に答える