我想使用boost::intrusive_ptr
来重新计算我的课程x::Y
,因此我为references
和release
函数添加了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
我认为我做过像升级文档所解释的那样,但似乎我做错了。问题在哪里?
答案 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_ref
和intrusive_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_ref
和intrusive_ptr_release
,即::x
,则会有效。
答案 5 :(得分:0)
第一个错误表明你没有包含任何提升标题。其余部分是因为第一个错误导致friend
声明上的解析失败。