5

私の友人は私に次のコードを見せてくれました

struct A {
  virtual void f() = 0;
  virtual void g() = 0;
};

struct AInternal : A {
  virtual void f() { /* ... */ }
  virtual void g() { /* ... */ }
};

彼はAInternal、ほとんど (すべてではないにしてもA) を実装する内部クラスとして使用しています。その後、彼は から継承しましAInternalたが、彼が望んでいたようにAInternal(これは実装の詳細であるため) アクセスできないままであり、保護された (実装された) を継承します。彼が行ったusingことは、基本クラス名をアクセス可能にすることでした (継承も保護Aされていたため、デフォルトで保護されていました)。AInternal

struct C : protected AInternal {
  using AInternal::A;
};

実際、これは問題なく動作しました (ただし、後でわかったように、メンバー関数は保持されていましprivateた。基本クラスが作成されpublicただけです)。ただし、GCC でしか動作しませんでした。ベースをAアクセス可能にできません。何か案が?Clang で動作するコードを壊すことさえできます

struct C : public AInternal {
protected:
  using AInternal::A;
};

C *c = 0;
A *a = c; // error on GCC!

誰か助けてくれませんか?

4

1 に答える 1

5

注入されたクラス名の可視性にのみ影響を与えています。基本サブオブジェクトまたはそのメンバーのアクセス保護は影響を受けません。Clang または GCC がキャストの有効性またはベース内のアクセスに影響を与えることを許可している場合、それは彼らのバグです。

[class.member.lookup] 10.2/3 は言う

宣言セットでは、using 宣言はそれらが指定するメンバーに置き換えられ、型宣言 (注入されたクラス名を含む) はそれらが指定する型に置き換えられます。

基本クラスのサブオブジェクトには、メンバー ルックアップで名前がありません。注入されたクラス名はそうです。

于 2013-07-15T03:11:15.153 に答える