Почему объявление частного базового класса делает имя типа недоступным?

Я удивлен, что в следующем примере объявление частного класса Мидла делает это имя недоступным как тип в последующем выводе.

class Base {
public:
Base(Base const& b) : i(b.i) {}

int i;
};

class Middle : private Base {            //<<<<<<<<<<<
public:
Middle(Base const* p) : Base(*p) {}
};

class Upper : public Middle {
public:
Upper(Base const* p) : Middle(p) {}    //<<<<<<<<<<<
};

Таким образом, компиляция с g ++ (Debian 6.3.0-18 + deb9u1) 6.3.0 20170516 …

g++ -std=c++11 privateBase.cpp

Я получаю следующую диагностику:

privateBase.cpp:15:9: error: ‘class Base Base::Base’ is inaccessible within this context
Upper(Base const* p) : Middle(p) {}
^~~~
privateBase.cpp:1:12: note: declared here
class Base {
^

Ясно, что в тот момент, когда Base использовался в качестве базового класса Middle, его имя было доступно как тип. Я могу понять это, когда Base используется для обозначения хранилища базового класса, которое должно быть приватным. Но объявление частного базового класса делает имя типа недоступным, по крайней мере, неожиданным.

10

Решение

Это предназначено; увидеть основной вопрос 175, который даже добавил пример, иллюстрирующий это в [class.access.spec] p5:

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

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

- конец примера ]


Это выпадает из взаимодействия между внедрением имени класса (для обоснования см. Почему вводится имя класса?) и тот факт, что в C ++ контроль доступа применяется после поиска имени, а не до.

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]