朋友功能和静态数据成员

时间:2015-04-11 05:55:12

标签: c++ friend

如何在朋友的功能体内使用名称进行不合格的名称查找?我们来考虑以下代码:

#include <iostream>

void foo();

class A
{
    friend void foo(){ std::cout << a << std::endl; }
    static int a;
};

int A::a = 10;

int main(){ foo(); }

DEMO

标准在N4296::7.3.1.2/3 [namespace.memdef]

中说明
  

如果非本地类中的朋友声明首先声明一个类,   朋友是其成员的函数,类模板或函数模板   最里面的封闭命名空间。

所以,我预计不合格的名字查找没有找到A::a,但确实如此。我故意将A::a声明放在朋友的功能定义之后,希望它不会被找到。朋友的不合格名称查找的实际规则是什么?

1 个答案:

答案 0 :(得分:4)

答案很简单:

N4296::3.4.1/8 [basic.lookup.unqual]

  

对于类X的成员,在成员函数中使用名称   正文 ,在默认参数中,在例外规范中,在   非静态数据成员(9.2)的支持或等于初始化程序,或在   X定义之外的类成员的定义,   在成员的声明者-id31之后,应在其中一个声明   以下方式:

     

[...]

     

(8.2) - 应该是X类的成员或者是基类的成员   X(10.2),

     

[...]

N4296::3.4.1/9 [basic.lookup.unqual]

  

朋友功能定义中使用的名称的名称查找   (11.3)授予友谊的类中的 定义内联 将继续进行   如 在成员函数定义中查找

所述

那就是它。

UPD:

内联 非常重要。这就是为什么在类定义之外定义的友元函数不能直接使用该类的静态成员的原因。例如,以下代码会编译编译时错误:

#include <iostream>

class A
{
    static int a;
    friend void foo();
};

int A::a = 10;

void foo(){ std::cout << a << std::endl; }



int main(){ foo(); }

<强> DEMO