Re: Visibility and dependent base class
Kaba <none@here.com> writes:
template <typename Type>
class Base
{
public:
enum {VALUE = 1};
typedef int Value;
void g() {}
};
template <typename Type>
class Derived: public Base<Type>
{
public:
void f()
{
// These do not compile...
Value value = VALUE;
g();
The names Value, VALUE and g are unqualified. Unqualified names are
looked up by the compiler during the first of two phases; in that
phase, names inherited from Base<Type> are not considered. The reason
is that your code might later specialize template Base in a way that
doesn't declare the three names or declare them to mean something
different than what the Base base template declares them to mean.
E.g. the definition of template Derived might be followed by
template <>
class Base<int>
{
public:
int Value;
double g;
};
It's hard to figure out which versions of Value and g should be
considered when specializing Derived for int, so the Standards
committees decided that none from template Based should.
The solution is to qualify the three names, so that they are looked up
in the second phase, when specializations are taken into
consideration. There are two options, both illustrated in the
following snippet:
Base<Type>::Value value = Base<Type>::VALUE;
this->g();
Doing this adds another problem, though:
The name Base<Type>::Value is a "dependant name" (i.e. its meaning
depends on the template parameter). The compiler has to assume that
such names do not name types unless the code explicitly says so, as
in:
typename Base<Type>::Value value = Base<Type>::value;
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]