在阅读Karlsson的超越C ++标准时,作者在 class reference_counted 的主体中定义了朋友函数 intrusive_ptr_add_ref (参见第36页)。在适当的时候使用Argument Dependent Lookup自动调用该函数。
从未见过在类体中定义的友元函数,我玩过并发现如果不使用ADL查找,gcc 4.4.3需要前向声明。实际上,如果没有前向声明,似乎无法引用 adl_no 。这是C ++标准的一部分还是gcc的神器? (我没有Windows框,所以无法尝试VC)。
#include <cstdlib>
#include <iostream>
namespace {
void adl_no(); // Remove this and it won't compile with gcc
struct Q {
friend void adl_yes(const Q&) {
std::cout << "adl_yes" << std::endl;
}
friend void adl_no() {
std::cout << "adl_NO" << std::endl;
}
};
}
int main(int argc, char** argv)
{
adl_yes(Q());
adl_no();
return EXIT_SUCCESS;
}
答案 0 :(得分:6)
是的,这种行为是标准的。该标准的相关部分是7.3.1.2 [namespace.memdef]第3段:
如果非本地类中的
friend
声明首先声明一个类或函数,那么友元类或函数是最内层封闭命名空间的成员。在该命名空间范围[...]中提供匹配的声明之前,通过简单的名称查找找不到该朋友的名称。如果调用了友元函数,则可以通过名称查找找到其名称,该名称查找考虑来自名称空间的函数和与函数参数的类型相关联的类(3.4.2)[即ADL]。