Согласно clang, gcc и vs2013, функция Outer::f
является не другом класса Outer::Inner
.
struct Outer {
void f() {}
class Inner {
friend void f();
static const int i = 0;
};
};
void f() { int i = Outer::Inner::i; }
Из [namespace.memdef]/3 я ожидал бы, что функция Outer::f
будет другом Outer::Inner
, а не ::f
, потому что объявление друга не является первым в его пространство имен, содержащее имя f
.
[namespace, memdef]/3 (акцент мой):
Каждое имя, впервые объявленное в пространстве имен, является членом этого Пространство имен. Если объявление друга в нелокальном классе сначалаобъявляет класс, функцию, шаблон или функцию класса template 97 друг является членом самого внутреннего охватывающее пространство имен. Декларация друга сама по себе не делает имя, видимое для неквалифицированного поиска (3.4.1) или квалифицированный поиск (3.4.3). [Примечание: имя друга будет видимым в его пространство имен, если в области пространства имен предоставляется соответствующее объявление (до или после определения класса, дающего дружбу). - end note] Если вызывается функция функции или шаблон функции, ее имя может быть найдено по имени, которое рассматривает функции из пространства имен и классы, связанные с типами функций аргументы (3.4.2). Если имя в объявлении друга не является или идентификатор шаблона, а декларация - это функция или разработанный тип-спецификатор, поиск, чтобы определить, является ли объект был ранее объявлен, не рассматривает какие-либо области вне внутреннее пространство имен.