This is nothing specific to clang but C++ access control and protected
access specifier.
The language specification wants to ensure that you are accessing a protected member of some base subobject that belongs to the derived class object. You are not supposed to be able access protected members of some unrelated independent objects of base type.
For this reason, you have to access protected members through pointer->member
syntax, reference.member
or object.member
syntax, where the pointer/reference/object refers to the derived class.
This is exactly inline with what you have shown in your example:
template<int N>
struct B
{
protected:
void f() {}
};
template<int N>
struct A : B<N>
{
A()
{
this->f(); // ok
f(); // error : use of undeclared identifier 'f'
}
};
Link:
Protected members are not as private as private members, which are accessible only to members of the class in which they are declared, but they are not as public as public members, which are accessible in any function.
Protected members that are not declared as static are accessible to friends and member functions in a derived class only through a pointer to, reference to, or object of the derived class.