从C ++中的私有模板类inheritance构造函数

为什么D类编译,但C类不?

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

我用GCC, Clang和Visual C ++进行了testing,它们都是一样的。 改变class B : private Tpublic T解决问题。 但为什么? (请注意, using T::Tpublic 。)

A在其范围内包含注入类名称A (即, A::A指向类A除非碰巧指向构造函数)。

B类inheritance了这一点,所以B范围内的名字A引用了A范围内的注入类名A 但是,由于AB的私有基类,因此B范围内的所有名称在B是私有的。

C类inheritance了这个,但是它不能访问这个A ,因为它在B是私有的。 因此,错误。 请注意,该错误实际上是在构造B<A>使用名称A

BA没有这个问题,因为定义B<A>不在任何类的范围内,所以名称A指的是全局名称A而不是任何注入类名。 当然, BA的名字是公开的。

您可以通过在C限定名称A来轻松解决此问题:

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

请注意构造函数的inheritance没有效果。 问题是访问名称A (注入A并在BCinheritance),而不是访问构造函数。