protected;
that is, its name can be used only by members and friends
of the class in which it is declared, by classes derived from that class, and by their
friends (see [class.protected]).
Because access control applies to names, if access control is applied to a
typedef name, only the accessibility of the typedef name itself is considered.
The accessibility of the entity referred to by the typedef is not considered.
For example,
class A {class B {};
public:typedef B BB;
};
void f(){
A::BB x; // OK, typedef name A::BB is public
A::B y; // access error, A::B is private} — end note]
Access to members and base classes is controlled, not their
visibility ([basic.scope.hiding]).
Names of members are still visible, and implicit conversions to base
classes are still considered, when those members and base classes are
inaccessible.
— end note]
The interpretation of a given construct is
established without regard to access control.
If the interpretation
established makes use of inaccessible member names or base classes,
the construct is ill-formed.
All access controls in [class.access] affect the ability to access a class member
name from the declaration of a particular
entity, including parts of the declaration preceding the name of the entity
being declared and, if the entity is a class, the definitions of members of
the class appearing outside the class's member-specification.
[Example 2: class A {typedefint I; // private member
I f();
friend I g(I);
static I x;
template<int>struct Q;
template<int>friendstruct R;
protected:struct B {};
};
A::I A::f(){return0; }
A::I g(A::I p = A::x);
A::I g(A::I p){return0; }
A::I A::x =0;
template<A::I>struct A::Q {};
template<A::I>struct R {};
struct D: A::B, A {};
Here, all the uses of
A::I
are well-formed because
A::f,
A::x, and A::Q
are members of class
A
and
g
and R are friends of class
A.
This implies, for example, that access checking on the first use of
A::I
must be deferred until it is determined that this use of
A::I
is as the return type of a member of class
A.
Similarly, the use of A::B as a
base-specifier is well-formed because D
is derived from A, so checking of base-specifiers
must be deferred until the entire base-specifier-list has been seen.
The names in a default argument ([dcl.fct.default]) are
bound at the point of declaration, and access is checked at that
point rather than at any points of use of the default argument.
Access checking for default arguments in function templates and in
member functions of class templates is performed as described in [temp.inst].
[Example 3: class B {};
template<class T>class C {protected:typedef T TT;
};
template<class U, class V =typename U::TT>class D :public U {};
D <C<B>>* d; // access error, C::TT is protected — end example]