Given the following code:
class A
{
protected:
A(){}; // compilation error
public:
void foo(){cout << "A\n";};
};
class B : public A
{
public:
B() { };
void foo(){
cout << "B\n";
A A(); // OK
A a1; // compilation error
}
};
If I changed the base class A
constructor to public
, the code compiles. How to explain this?
§11.4/1:
As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class
C
. If the access is to form a pointer to member (5.3.1), […].
All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall beC
or a class derived fromC
.
In your case, the access is implicit but nonetheless present. We are trying to access A
s constructor with the (implicit) object argument a1
. §11/6:
All access controls in Clause 11 affect the ability to access a class member name from the declaration of a particular entity […]. [ Note: this access also applies to implicit references to constructors, conversion functions, and destructors. — end note ]
However, a1
is not of type B
or a class derived from B
. Hence our above requirement is not met, and access control is not happy.