A derived class can call a protected base class constructor in its ctor-initializer, but only for its own base class subobject, and not elsewhere:
c
C++11 §11.2/5:
”
A memberm
is accessible at the point R when named in classN
if
m
as a member ofN
is public, or
m
as a member ofN
is private, and R occurs in a member or friend of classN
, or
m
as a member ofN
is protected, and R occurs in a member or friend of classN
, or in a member or friend of a classP
derived fromN
, wherem
as a member ofP
is public, private, or protected, orthere exists a base class
B
ofN
that is accessible at R, andm
is accessible at R when named in classB
.
For your constructor invocation
Base b2;
the 3rd point above applies. m
is the Base
constructor. N
, the naming class, is Base
. m
as a member of Base
is protected, and the declaration occurs in a member of class Derived
derived from Base
, but it's not the case that the Base
constructor as a member of Derived
is public, private or protected: it’s simply not a member of Derived
, constructors are not implicitly inherited.
I think the language “is public, private, or protected” is pretty awkward; I can only surmise that it’s the result of some evolution of this paragraph.
I have yet to find an explanation of how formally the protected Base
constructor is accessible in a member initializer list in Derived
, but then I just started looking at this for this question.
Update: I fail to find any language in the standard pertaining to access to constructors in an initializer list, and I fail to find any Defect Report about it. It’s quite possibly a defect.