Почему простое упоминание базового указателя/ссылки в последующих частных классах запрещено? - программирование

Почему простое упоминание базового указателя/ссылки в последующих частных классах запрещено?

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

Эта ошибка кажется мне необоснованной. Если мы сможем использовать простой B* в глобальной области, то почему бы и нет в его частных классах? демонстрация g++.

Мы не пытаемся преобразовать DD* в B*, что запрещено языковыми правилами (this, this, this - это связанные вопросы).
Обратите внимание: если я изменил B* foo() на int foo(), все будет хорошо.

4b9b3361

Ответ 1

Поэтому, по-видимому, компилятор считает, что B ссылается на частный конструктор B, а не на тип.

Квалификационный B, по-видимому, исправляет эту ошибку:

class B* foo () { return 0; }

или это:

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

Я не знаю, почему это происходит, но, возможно, это поможет.


Обновление: возможно, это связано с 11.2.4 стандарта? Единственная проблема в том, что мой стандарт не достаточно хорош, чтобы полностью понять его.

(извините за изображение, копирование/вставка не работает для меня)

Ответ 2

Быстрый поиск имени введенного класса в стандарте дает:

§11.1 [class.access.spec]

5/ [Примечание. В производном классе поиск имени базового класса найдет имя введенного класса вместо имени базового класса в области, в которой он был объявлен. Имя введенного класса может быть менее доступным, чем имя базового класса в области, в которой оно было объявлено. -end note]

[Пример:

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

-end пример]

Я считаю, что это очень близко к вашему примеру;)


Примечание clang 3.0 stack, который немного более явный:

$ 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, а не непосредственно в глобальном пространстве имен.

Ответ 3

Мое лучшее предположение, что это не запрещено, С++ просто не видит тип B внутри этого оператора или, в лучшем случае, метка B ничего не значит.

Несколько хороших читайте о