Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing inherited variable from templated parent class [duplicate]

The later GCC versions correctly implement the standard.

The standard specifies that unqualified names in a template are non-dependent and must be looked up when the template is defined. The definition of a dependent base class is unknown at that time (specializations of the base class template may exist) so unqualified names are unable to be resolved.

This is true for both variable and function names declared in the base class.

As you have observed the solution is to provide the qualified name of the variable or function, or to provide a "using" declaration. E.g.

template<class T> 
int Bar<T>::Perna(int u) 
{ 
  int c = Foo<T>::a * 4; // This works
  c = this->a * 4; // and this

  using Foo<T>::a; 
  c = a * 4; // and with 'using', so should this
}

(I'm actually not 100% sure about the correct syntax for the using version and can't test from here, but you get the idea).


The error message that GCC gives shows that your version of GCC still had a bug that is only resolved in GCC4.7 trunk versions. Older versions, including GCC4.1 will happily accept following code

template<typename T>
struct A {
  void f(int) { }
};

template<typename T>
struct B : A<T> {
  void g() { T t = 0; f(t); }
};

int main() {
  B<int> b; b.g();
}

GCC will look up f in f(t) within the base class A<T> and will find the declaration in the base class. GCC does that because f is dependent, because there are arguments to f that "depend on a template parameter" (look at its error message it gave you!). But the Standard forbids GCC to do that for two reasons

  1. The Standard says that use of unqualified names will never find a declaration in a dependent base class no matter whether the name is dependent.

  2. The Standard says that dependent lookup of a function name at instantiation time will only do ADL.

GCC 4.7 implements the Standard correctly in that regard.