0

我想boost::intrusive_ptr用于引用我的 class x::Y,所以我为and函数添加了一个references字段和朋友声明,它们应该在 namespace 中定义。然后,我编写这些函数。像这样:releaseadd_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

我以为我做了 boost 文档中解释的所有事情,但似乎我做错了什么。哪里有问题?

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名称空间中,而是放在包含您的类的名称空间中(即 in 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;
    }
}

编辑:如果您希望将它们放在 boost 命名空间中,则可以改为通过在类之前使用这两个函数声明来声明 boost 命名空间。

于 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_refand ,它将起作用,即在.intrusive_ptr_release::x::Y::x

于 2012-08-31T14:29:21.223 回答
0

第一个错误表明您没有包含任何提升标头。其余是因为第一个错误导致friend声明解析失败。

于 2012-08-31T14:32:35.020 回答