14
struct B {};
struct D : private B {
  B* fun () { return new D; }  // ok
}
struct DD : public D {
  B* foo () { return 0; } // error: ‘struct B B::B’ is inaccessible !
};

このエラーは私には不合理に思えます。グローバル スコープでsimple を使用できるのであればB*、プライベートに派生したクラスで使用できないのはなぜですか? g++ デモ

言語規則で禁止されている に変換しようとはしていません ( DD*this 、thisthis関連する質問です)。に変更すると、うまくいくこと に注意してください。B*
B* foo()int foo()

4

3 に答える 3

7

したがって、コンパイラは、型ではなくBプライベートコンストラクターを参照していると考えているようです。B

予選Bは明らかにそのエラーを修正します:

class B* foo () { return 0; }

またはこれ:

::B* foo () { return 0; }

なぜそれが起こっているのかわかりませんが、おそらくこれが役立つでしょう。


更新: 標準の 11.2.4 に関連している可能性がありますか? 唯一の問題は、私の標準語が十分に理解できないことです。

(画像で申し訳ありません、コピー/貼り付けはうまくいきません)

于 2012-12-18T06:02:56.300 に答える
7

標準での注入されたクラス名の簡単なルックアップは次のようになります。

§11.1 [class.access.spec]

5/ [注:派生クラスでは、基本クラス名のルックアップは、それが宣言されたスコープ内の基本クラスの名前ではなく、注入されたクラス名を見つけます。注入されたクラス名は、それが宣言されたスコープ内の基本クラスの名前よりもアクセスしにくい場合があります。—終わりのメモ]

[ 例:

class A { };
class B : private A { };
class C : public B {
    A *p; // error: injected-class-name A is inaccessible
    ::A *q; // OK
};

—終わりの例]

これはあなたの例に不気味に近いと思います;)


もう少し明示的なclang 3.0のスタックに注意してください。

$ clang++ -fsyntax-only test.cpp
test.cpp:6:5: error: 'B' is a private member of 'B'
    B* foo () { return 0; } // error: ‘struct B B::B’ is inaccessible !
    ^
test.cpp:2:12: note: constrained by private inheritance here
struct D : private B {
           ^~~~~~~~~
test.cpp:1:8: note: member is declared here
struct B {};
       ^
1 error generated.

ここでは、グローバル名前空間で直接取得されるのではなく、 をB介してアクセスされることがわかります。D

于 2012-12-18T07:45:51.517 に答える
1

私の推測では、これは禁止されていません。C++は、そのステートメント内にBタイプを認識しないか、より適切に言えば、ラベルBは何も意味しません。

いくつかの良い読み物

于 2012-12-18T06:14:26.280 に答える