调用struct中定义的友元函数需要转发声明吗? 在阅读卡尔森超越C++标准时,作者定义了 >类引用> < >(参见PG 36)中的Fuffic函数 IsIssivEpTrpAddiaRef> 。在适当的时间使用参数相关的查找自动调用该函数

调用struct中定义的友元函数需要转发声明吗? 在阅读卡尔森超越C++标准时,作者定义了 >类引用> < >(参见PG 36)中的Fuffic函数 IsIssivEpTrpAddiaRef> 。在适当的时间使用参数相关的查找自动调用该函数,c++,friend,C++,Friend,我从来没有见过在类的主体中定义的友元函数,我仔细研究了一下,发现GCC4.4.3如果不使用ADL查找,就需要一个前向声明。事实上,如果没有这一前瞻性声明,似乎无法引用adl_no。这是C++标准的一部分还是GCC的一个伪像?(我没有Windows box,因此无法尝试VC) #包括 #包括 名称空间{ void adl_no();//删除此项,它将不会使用gcc编译 结构Q{ friend void adl_是(const Q&){ std::cout是的,这种行为是标准的。标准的相关部分是7.

我从来没有见过在类的主体中定义的友元函数,我仔细研究了一下,发现GCC4.4.3如果不使用ADL查找,就需要一个前向声明。事实上,如果没有这一前瞻性声明,似乎无法引用adl_no。这是C++标准的一部分还是GCC的一个伪像?(我没有Windows box,因此无法尝试VC)

#包括
#包括
名称空间{
void adl_no();//删除此项,它将不会使用gcc编译
结构Q{
friend void adl_是(const Q&){

std::cout是的,这种行为是标准的。标准的相关部分是7.3.1.2[namespace.memdef]第3段:

如果非本地类中的
friend
声明首先声明了一个类或函数,则friend类或函数是最内层封闭命名空间的成员。在该命名空间范围中提供匹配声明之前,通过简单的名称查找无法找到friend的名称[…]。如果调用友元函数,则可以通过名称查找找到其名称,该名称查找考虑与函数参数类型(3.4.2)[即ADL]关联的名称空间和类中的函数


Comeau在线行为与gcc匹配,所以不太可能出错。还没有为您搜索标准,因为我认为您可以像我一样轻松地做到这一点…;-P.Cute.移动adl_no()的声明从之前到之后,struct Q的定义都是有效的。确实是一个迷宫,有很多曲折的小段落,它们都是一样的。@themis:是的,当你使用语言中晦涩难懂的部分时(比如在类中定义一个友元函数),它们会变得紧凑而曲折。
#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;
}