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

时间:2016-08-23 12:58:11

标签: c++ templates language-lawyer

为什么类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::Tpublic。)

1 个答案:

答案 0 :(得分:42)

A在其范围内包含注入类名A(即A::A引用类A,除非它恰好引用构造函数)

B继承此内容,因此A范围内的名称B引用A范围内的注入类名A 。但是,由于AB的私有基类,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并在AB中继承),而无法访问构造