1
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'
    }
};

int main()
{
    A<8> a;
}

My C++ compiler is clang 3.8.

Why doesn't clang allow a derived class to call a protected base function?

xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • 1
    Use `B::f()`, that's not clang specific. – πάντα ῥεῖ Sep 16 '16 at 09:42
  • `this->f();` or `B::f()` – Danh Sep 16 '16 at 09:42
  • 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. – Abhishek Jain Sep 16 '16 at 09:54
  • This has nothing to do with protected; the same problem would come up if `f()` was public. It's about name lookup, not access control. – Pete Becker Sep 16 '16 at 12:45

1 Answers1

-2

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.

Abhishek Jain
  • 9,614
  • 5
  • 26
  • 40
  • fyi that code will be failed to compile when change `protected` to `public` – Danh Sep 16 '16 at 09:45
  • 1
    I flagged this one as not an answer, the answer can be found by that duplicated question. – Danh Sep 16 '16 at 09:47
  • 1
    @Danh While the question was answered elsewhere, that doesn't make this any less of an answer. This answer is perfectly valid (whether it's correct or not, I have no idea - this is not my expertise), and is not plagiarizing the existing answer on the duplicate question. Please don't raise false flags simply because the answerer isn't aware of all of the other 39528191 questions and answers that came before it. – Siyual Sep 16 '16 at 13:55