Является ли следующий пример корректным?
namespace N {
class A;
}
using namespace N;
class B {
int i;
friend class A;
};
namespace N {
class A {
B m;
int get() { return m.i; }
};
}
Этот пример успешно скомпилирован с Clang 3.5, но не с g++ 4.8.1 со следующим:
main.cpp: In member function ‘int N::A::get()’:
main.cpp:7:9: error: ‘int B::i’ is private
int i;
^
main.cpp:14:30: error: within this context
int get() { return m.i; }
^
С++ 11 standard §7.3.1.2 p3 говорит,
Если имя в объявлении
friend
не является ни квалифицированным, ни идентификатором шаблона, а декларация является функцией или специфицированным спецификатором типа, поиск для определения того, был ли объект ранее объявлен, не должен рассматривать какие-либо области вне самого внутреннего охватывающего пространства имен.
В примере class A
не входит в внутреннее пространство имен (т.е. глобальное пространство имен), но class A
вводится с помощью директивы в глобальное пространство имен.