2010-08-29 68 views
4

在阅读卡尔森的超越C++标准作者在类的主体限定的朋友函数intrusive_ptr_add_ref reference_counted(见第36页)。该函数在适当的时候使用参数相关查找自动调用。调用结构中定义的朋友函数需要前向声明?

从未见过在类的主体中定义的朋友函数,我玩过并发现如果不使用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

Comeau在线行为与gcc匹配,因此不太可能是错误的。没有为您搜索标准,因为我认为您可以尽可能轻松地做到这一点...... ;-P。 – 2010-08-29 00:33:58

回答

5

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

如果friend声明在非局部类首先声明类或函数朋友类或函数是的一个构件最内层的封闭名称空间。直到在该名称空间范围[...]中提供了匹配声明之后,通过简单名称查找才能找到该朋友的名称。如果调用好友函数,则其名称可以通过名称查找找到,该名称查找考虑了与函数参数类型(3.4.2)相关的名称空间和类的函数[即ADL。

+0

可爱。将adl_no()的声明从struct Q的定义之前移动到后面。真正的曲折小道的迷宫都是一样的。 – themis 2010-08-29 01:10:38

+0

@themis:是的,当你使用语言的晦涩部分时(比如在课堂中定义好友功能),他们会变得紧张和曲折。 – 2010-08-29 02:10:46