为什么类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 A A::A' is inaccessible
}; // within this context
using BA = B<A>;
class D : public BA
{
public:
D() : BA(123) {} // OK
};
我使用GCC,Clang和Visual C ++进行了测试,它们都是一样的。
将class B : private T
更改为public T
可解决问题。但为什么? (请注意,using T::T
为public
。)
答案 0 :(得分:42)
类A
在其范围内包含注入类名A
(即A::A
引用类A
,除非它恰好引用构造函数)
类B
继承此内容,因此A
范围内的名称B
引用A
范围内的注入类名A
。但是,由于A
是B
的私有基类,A
范围内的所有名称都在B
内是私有的。
类C
再次继承此内容,但无法访问此A
,因为它在B
内是私有的。因此错误。请注意,错误实际上是使用构造A
中的名称B<A>
。
类BA
没有此问题,因为定义B<A>
不在任何类的范围内,因此名称A
引用全局名称{{ 1}}而不是任何注入类名。当然,名称A
是公开的。
您可以通过在BA
中确定名称A
来轻松解决此问题:
C
请注意,构造函数继承在那里没有效果。问题在于访问类名称class C : public B<A>
{
public:
C() : B<::A>( 123 ) {}
};
(注入A
并在A
和B
中继承),而无法访问构造