我想了解一些引起PC-Lint悲伤的boost代码,并以某种方式使用friend关键字,这种方式我并不认为是合法的C++,但在VS2008中编译好。为什么朋友函数会被定义为struct - boost thread_data的一部分?
我以为我理解朋友是一种声明类和函数的方法。我不认为用这种函数定义是合法的。但是,the MSDN page是非常具体的:
朋友函数可以在类声明中定义。这些函数是内联函数,并且像成员内联函数一样,它们的行为就好像在所有类成员已经被查看之后但在类作用域关闭之前(类声明结束)一样。
在类声明中定义的朋友函数不在封闭类的范围内考虑;他们在文件范围内。
所以我明白,这是合法的,如果不寻常的语法。
我不确定它是如何得到它们的,因为声明某个朋友的正常原因是为了增加访问权限。然而,一个结构的成员默认都是公共的,所以这里没有这样的好处。
我是否缺少深奥的东西,或者这只是一些文体提升问题,有人不喜欢在结构的主体之后放置内联自由函数?
请注意,_InterlockedIncrement是Win32上的内部函数。
# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement
struct thread_data_base
{
long count;
detail::win32::handle_manager thread_handle;
detail::win32::handle_manager interruption_handle;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
boost::detail::tss_data_node* tss_data;
bool interruption_enabled;
unsigned id;
thread_data_base():
count(0),thread_handle(detail::win32::invalid_handle_value),
interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
thread_exit_callbacks(0),tss_data(0),
interruption_enabled(true),
id(0)
{}
virtual ~thread_data_base()
{}
friend void intrusive_ptr_add_ref(thread_data_base * p)
{
BOOST_INTERLOCKED_INCREMENT(&p->count);
}
...
};
更新
得益于以下Chubsdad的答案,我想我明白,现在,我发生了什么事的总结:
- 他们希望这些表现得像免费功能,让你可以只编译
intrusive_ptr_add_ref(somePtrToThreadData)
- 如果它们是在结构体后面定义的自由函数,它们将在全局命名空间中可见
- 把它们的结构内与朋友预选赛意味着它们的作用域的结构里面,但不是成员函数,这样的行为更像静态函数
- Argument-dependent Lookup意味着使用时就好像它们是免费的功能
-
他们会被发现
- 它们的行为如同它们是使用自由函数的语法(考虑,而不是在其上调用的显式数据块作为PARAM)
很坦率地说它看起来毫无意义,也许'friend'关键字强制函数以某种模糊的方式内联? – 2010-09-03 01:16:27
何时在代码中注释时,您需要一个? :) – 2010-09-03 01:18:59
难道这是解决模板类的依赖类型问题的方法吗? - 可能会查找朋友不在的位置,或许?顺便说一句,AFAIK使这个朋友不太可能强迫这个内联比成为它的成员 - 但有理由使用“内联”语法的朋友(例如看看巴顿 - 纳克曼的伎俩 - http:// en.wikipedia.org/wiki/Barton-Nackman_trick)。 – Steve314 2010-09-03 01:40:13