Правильно ли построен следующий пример?
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 §7.3.1.2 p3 говорит,
Если имя в объявлении
friend
не является ни квалифицированным, ни идентификатором-шаблона, а объявление является функцией или уточненным-спецификатором-типа, поиск, чтобы определить, является ли объект было объявлено ранее, не должны учитывать какие-либо области за пределами самого внутреннего объемлющего пространства имен.
Например, class A
не является членом самого внутреннего окружающего пространства имен (т. е. глобального пространства имен), но class A
вводится с помощью директивы using в глобальное пространство имен.
N
внутри N из-заusing namespace N
, попробуйте удалить последнийnamespace N
- person JuanR   schedule 09.01.2014using namespace N
не означает, что все последующее неявно принадлежитnamespace N
- person Praetorian   schedule 09.01.2014get()
. (ИМО....) - person jrok   schedule 09.01.2014friend class N::A
, похоже, также решает проблему. - person JuanR   schedule 09.01.2014using N::A;
вместоusing namespace N;
прекрасно компилируется. Я готов классифицировать это как ошибку. - person Rapptz   schedule 09.01.2014friend A;
тоже компилируется. - person TemplateRex   schedule 09.01.2014;
идентификатор просматривается в соответствии с 3.4.1 [поиск неквалифицированного имени], но игнорируются все неполные -типы имен, которые были объявлены. - person dyp   schedule 10.01.2014