我试图理解一些导致 PC-Lint 问题的 boost 代码,并以我认为不合法的 C++ 但在 VS2008 中编译正常的方式使用 friend 关键字。
我以为我理解 friend 是一种声明类和函数的方式。我认为在这样的函数定义上使用是不合法的。然而,the MSDN page非常具体:
友元函数可以在类声明中定义。这些函数是内联函数,并且与成员内联函数一样,它们的行为就像是在看到所有类成员之后但在类作用域关闭之前(类声明的末尾)立即定义的。
在类声明中定义的友元函数不在封闭类的范围内;它们在文件范围内。
所以我知道这是合法的,即使是不寻常的语法。
我不确定他们得到了什么,因为将某物声明为 friend 的正常原因是增加访问权限。但是,默认情况下结构的成员都是公共(public)的,因此这里没有这样的好处。
我是否遗漏了一些深刻的东西,或者这只是一些风格上的 boost 问题,有人不喜欢在结构体之后放置内联自由函数?
请注意,_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意味着它们将在使用时被发现,就好像它们是免费功能一样
- 上述组合意味着它们的行为就像是使用自由函数语法的虚函数(将显式数据 block 作为参数而不是对其调用)
最佳答案
在类定义中定义“友元”函数是完全没问题的。在这种特殊情况下,由于友元函数采用 thread_data_base
类型的参数,因此友元函数定义仅在 ADL(参数相关查找)$3.4.2 的词法范围之外调用时可见类定义
查看 Namespace and the Interface Principle来自 Herb Sutter
关于c++ - 为什么要将友元函数定义为结构的一部分 - boost thread_data?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3632349/