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.