Наследование конструктора из частного шаблона в C ++

Почему компиляция classа D , но class C нет?

 class A { public: A(int) {} }; template  class B : private T // Note: private base class { public: using T::T; }; class C : public B { public: C() : B(123) {} // Error: 'class AA::A' is inaccessible }; // within this context using BA = B; class D : public BA { public: D() : BA(123) {} // OK }; 

Я тестировал GCC, Clang и Visual C ++, и они все одинаковы. Изменение class B : private T для public T решает проблему. Но почему? (Обратите внимание, что using T::T является public .)

Класс A содержит введенное имя classа A в своей области (то есть A::A относится к classу A если только это не относится к конструктору).

Класс B наследует это, поэтому имя A пределах области B относится к введенному classу-имени A в области A Однако, поскольку A является частным базовым classом B , все имена в области A являются частными внутри B

Класс C снова наследует это, но он не может получить доступ к этому A , поскольку он является частным внутри B Отсюда и ошибка. Обратите внимание, что ошибка на самом деле связана с использованием имени A в конструкции B .

Класс BA не имеет этой проблемы, так как определение B не входит в сферу применения любого classа, поэтому имя A относится к глобальному имени A а не к любому впрыснутому classу-имени. И, конечно же, имя BA является публичным.

Вы можете легко решить это, присвоив имя A в C :

 class C : public B { public: C() : B<::a>( 123 ) {} }; 

Обратите внимание, что наследование конструктора не действует. Проблема заключается в доступе к имени classа A (введенному в A и унаследованному в B и C ), а не к доступу к конструктору.