13

次の例は整形式ですか?

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; }
                              ^

C++11 標準 §7.3.1.2 p3 によると、

宣言内の名前がfriend修飾されておらず、テンプレート IDでもなく、宣言が関数または精巧な型指定子である場合、エンティティが以前に宣言されているかどうかを判断するためのルックアップでは、最も内側にある名前空間の外側のスコープは考慮されません。

たとえば、最も内側にある名前空間(つまり、グローバル名前空間)class Aのメンバーではありませんが、ディレクティブを使用してグローバル名前空間に導入されます。class A

4

2 に答える 2

1

名前空間 N を使用すると、名前 N::A がグローバル名前空間に取り込まれますが、グローバル名前空間でその A を宣言することにはなりません。したがって、グローバル名前空間の追加の A は B のフレンドです。clang は間違っています。

于 2014-01-09T20:34:53.603 に答える