friendクラスの宣言とusingディレクティブ
-
21-12-2019 - |
質問
次の例は整形式ですか?
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; }
};
}
この例はClang3.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; }
^
C++11標準§7.3.1.2p3は言う,
名前がaの場合
friend
宣言は資格もaでもありません テンプレートid そして、宣言は関数または elaborated-type-specifier, 、エンティティが以前に宣言されているかどうかを判断するルックアップは、最も内側を囲む名前空間の外のスコープを考慮してはなりません。
例では, class A
のメンバーではありません 最も内側を囲む名前空間 (つまりグローバル名前空間)ですが、 class A
ディレクティブを使用してグローバル名前空間に導入されます。
解決
名前空間Nを使用してn::Aという名前をグローバル名前空間にプルしている間、グローバル名前空間でAを宣言していません。したがって、グローバル名前空間の追加のAはBの友です。clangは間違っています。
他のヒント
作るために N::A
資格なしa friend
の B
あなたが使うだろう
friend A;
よりもむしろ
friend class A;
精緻化された型指定子を使用する場合、つまり, class A
, この特定の形式では、クラス名を導入します(3.4.4[基本]を参照してください。ルックアップ。elab]パラグラフ2)。
所属していません StackOverflow