简体   繁体   中英

Inheriting a constructor from a private template class in C++

Why does class D compile, but class C does not?

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
};

I tested with GCC, Clang and Visual C++, and they are all the same. Changing class B : private T to public T solves the problem. But why? (Note that the using T::T is public .)

Class A contains the injected-class-name A within its scope (that is, A::A refers to class A unless it happens to refer to the constructor).

Class B inherits this, so the name A within the scope of B refers to the injected-class-name A in scope of A . However, since A is a private base class of B , all names in scope of A are private within B .

Class C again inherits this, but it cannot access this A , since it is private within B . Hence the error. Note that the error is actually with using the name A in the construct B<A> .

Class BA doesn't have this problem, since the definition B<A> is not in the scope of any class, so the name A refers to the global name A and not to any injected-class-name. And of course, the name BA is public.

You can easily solve this by qualifying the name A in C :

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

Note that constructor inheritance has no effect there. The problem is with access to the class name A (injected in A and inherited in B and C ), not with access to the constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM