问题
How is unqualified name lookup being performed for names using within the friend's function body? Let's consider the following code:
#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
The Standard states in the N4296::7.3.1.2/3 [namespace.memdef]
:
If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace.
So, I expected unqualified name lookup didn't find A::a
, but it did. I deliberately put the A::a
declaration after the friend's function definition in hope it wouldn't be found. What's the actual rule for the friend's unqualified name lookup?
回答1:
The answer was quite simple:
N4296::3.4.1/8 [basic.lookup.unqual]
:
For the members of a class X, a name used in a member function body, in a default argument, in an exceptionspecification, in the brace-or-equal-initializer of a non-static data member (9.2), or in the definition of a class member outside of the definition of X, following the member’s declarator-id31, shall be declared in one of the following ways:
[...]
(8.2) — shall be a member of class X or be a member of a base class of X (10.2),
[...]
N4296::3.4.1/9 [basic.lookup.unqual]
:
Name lookup for a name used in the definition of a friend function (11.3) defined inline in the class granting friendship shall proceed as described for lookup in member function definitions.
That's it.
UPD:
Inlining is important here. That's why the friend function defined outside the class defintion cannot use static members of the class directly. For instance, the following code pritns compile-time error:
#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
来源:https://stackoverflow.com/questions/29574616/friend-functions-and-static-data-members