C ++ intrusive_ptr问题

时间:2012-08-31 14:25:02

标签: c++ boost namespaces smart-pointers forward-declaration

我想使用boost::intrusive_ptr来重新计算我的课程x::Y,因此我为referencesrelease函数添加了add_ref字段和好友声明,应在命名空间boost中定义。然后,我写这些功能。像这样:

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

我认为我做过像升级文档所解释的那样,但似乎我做错了。问题在哪里?

6 个答案:

答案 0 :(得分: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将通过依赖于参数的名称查找找到正确的版本。这不需要在课前进行任何声明。

答案 1 :(得分:2)

在这个特殊的最小代码中,你似乎遗漏了一些影响

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

一开始。也就是说,向前声明Y并声明你的函数。虽然为什么你只想把你的函数放到他们不属于的命名空间中,但是你想要经历这种痛苦。

答案 2 :(得分: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命名空间来做到这一点。

答案 3 :(得分: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

答案 4 :(得分:0)

如果您在与::x::Y类相同的命名空间中定义intrusive_ptr_add_refintrusive_ptr_release,即::x,则会有效。

答案 5 :(得分:0)

第一个错误表明你没有包含任何提升标题。其余部分是因为第一个错误导致friend声明上的解析失败。