首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

再度纠结于友元声明是否向外围引入名字

2012-08-27 
再次纠结于友元声明是否向外围引入名字C++标准:3. A function first declared in a friend declaration ha

再次纠结于友元声明是否向外围引入名字
C++标准:

3. A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retains its previous linkage (7.1.1).

按照3中说的,下面代码是应该通过的

C/C++ code
class X{    friend void f(); };int main(){    f(); //因为类X中的友元函数f的声明有外部链接,所以,f可见}void f() { /* ok to define friend function in the class body */ }

编译测试:
VC2005/2010通过 ,而GCC 4.4.3报错:无法找到名字f


5. A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8),the function name is unqualified, and the function has namespace scope. 
[Example:
class M {
  friend void f() { } // definition of global f, a friend of M,
  // not the definition of a member function
};
—end example] 
Such a function is implicitly inline. A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).

按照5中说的,既然在类中定义友元函数f,是"definition of global f",那么也就可以理解为下面的代码是可以通过编译的
C/C++ code
class X{    friend void f(){ /* ok to define friend function in the class body */ }};int main(){    f(); } 

然而VC2005/2010和GCC4.4.3都不能通过

TCPL中对友元有如下说明:
  “一个友元声明不会给外围的作用域引进一个名字”  
  “一个友元函数或者需要在某个外围作用域里显式声明,或者以它的类或由该类派生的类作为一个参数(13.6节),否则就无法调用这个友元了。” 

C++ primer有如下:
  “友元声明将已命名的类或非成员函数引入到外围作用域中。此外,友元函数可以在类的内部定义,该函数的作用域扩展到包围该类定义的作用域。”  
  “用友元引入的类名和函数(定义或声明),可以像预先声明的一样使用” 
C++ primer中的例子: 
class X { 
  friend class Y; 
  friend void f() { /* ok to define friend function in the class body */ } 
}; 
class Z { 
  Y *ymem; // ok: declaration for class Y introduced by friend in X 
  void g() { return ::f(); } // ok: declaration of f introduced by X 
}; 



标准中说的和C++ PRIMER一样,而和TCPL不一样。
至于编译器,GCC做的和TCPL说的一样,而VC和标准说的部分一样(对于在友元声明出定义函数处有出入)

个人总结
两个编译器行为不同,所以尽量提前声明友元所声明的名字

以上只是个人的看法,如果有不对的地方,恳请各位大大指正

[解决办法]
别纠结了,凡这么需要你搬标准才能判断行为的代码,就可以认为是一种错误了。
所以,懂了又有何用。

热点排行