This has nothing to do with the member being protected; you'd get the exact same error with a public member.
The real reason is that templates are involed. More specifically, that your class template has a base class which depends on a template parameter. This means that when parsing the template, the compiler will not (be able to) look into that base class to find inherited members which are used unqualified. It makes sense: when the template is parsed, the template parameter values are not known yet and thus the compiler has no idea what members the base class will have (remember partial and total specialisation exist!).
In order to overcome this, you must somehow tell the compiler that the name foo
depends on template parameters (that it's a dependent name). Once you do so, the compiler will not try to resolve it when parsing the template; it will postpone resolution until the template is instantiated. At that point, template arguments are known and thus the base class can be checked.
You have three ways to mark a member name as dependent:
Refer to the name through
this
, as you're doing:this->foo
Refer to the name through base-class qualification:
BaseClass<T>::foo
Bring the name into the scope of the derived class:
template<class T> class DerivedClass : public BaseClass<T> { protected: using BaseClass<T>::foo; // from this point on, `foo` is a dependent name public: void incr_foo() { ++foo; // works fine now } };