Home > other >  Making base class protected constructor public in derived class
Making base class protected constructor public in derived class

Time:07-25

Can someone please explain why the marked line does not compile? It seems to me that if B2 and D compile, B1 should too.

class A1 {
  protected:
    A1(int){}
};
class B1 : private A1 {
  public:
    using A1::A1;
};

class A2 {
  protected:
    A2(int){}
};
class B2 : private A2 {
  public:
    B2(int i) : A2(i) {}
};

class C {
  protected:
    void f(int) {}
};
class D : private C {
  public:
    using C::f;
};

int main() {
    // B1 b1(1); // error: calling a protected constructor of class 'A1'
    B2 b2(1);

    D d;
    d.f(1);
}

CodePudding user response:

using-declaration behaves differently when designating constructors vs other members. For constructors, the visibility of the using-declaration is ignored; if selected by overload resolution, the constructor can be used if it's visible in the base class. For all other members, using-declaration introduces a synonym into the derived class' scope, and that synonym has the visibility of the using-declaration.

[namespace.udecl]/19 A synonym created by a using-declaration has the usual accessibility for a member-declaration. A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored.

  • Related