While recently migrating older code (with permissive-), I found one small item that I didn't expect. The derived class could no longer access a protected variable without fully qualifying the name. Consider this very contrived example:
// CVTW == contrived value type wrapper
template<typename VALUE_TYPE>
class CVTW
{
public:
explicit CVTW(VALUE_TYPE const value) : _value { value }
{ }
protected:
VALUE_TYPE _value; // <-- target in question
};
// . . . . . . . . . . . . . .
class IntValueType : public CVTW<int>
{
public:
using CVTW<int>::CVTW;
int GetValue() const { return _value; } // <-- compiles
};
// . . . . . . . . . . . . . .
template<typename VALUE_TYPE>
class CTVW_2 : public CVTW<VALUE_TYPE>
{
// another solution to successfully access _value directly
//using CVTW<VALUE_TYPE>::_value;
public:
using CVTW<VALUE_TYPE>::CVTW;
VALUE_TYPE GetValue() const
{
//return _value; // <-- error
return CVTW<VALUE_TYPE>::_value; // <-- compiles
}
};
// . . . . . . . . . . . . . .
int main()
{
IntValueType v { 1 };
CTVW_2<int> v2 { 2 };
}
When attempting to access _value
from CTVW_2
(without fully qualifying the name or a using statement) the following error is reported:
error: use of undeclared identifier '_value'
I realize this has nothing to do with protected access scope, and I have some understanding of name hiding and the fragile base problem, but in this case, why is this necessary and why is there no error reported when IntValueType
accesses the same variable in the same manner?
EDIT: Here is a working example. MSVC isn't as picky, but Clang and GCC report the issue.