Question

Consider the following example:

template <typename T>
struct A {
  struct B {
    int b;
  };

  struct C : B {
    void f() {
      b = 0;
    }
  };
};

Compiling it with GCC 4.8.1 gives the following error:

test.cc: In member function ‘void A<T>::C::f()’:
test.cc:9:11: error: ‘b’ was not declared in this scope
           b = 0;
           ^

However, b is a member of the parent class B (I used struct in the example to make everything public) and if I make A non-template everything compiles.

Why is the compiler giving this error and how can I avoid it?

Was it helpful?

Solution

This is kind of an obscure corner case in the language, but the solution is simple, qualify it:

this->b = 0; // alternatively 'B::b = 0;'

The reason is that without the qualification b is not a dependent name, and it needs to be resolved in the first pass of lookup, before the actual type is substituted into the template. At this point the compiler does not know whether there can be an specialization of A<T>::B for the type that will be instantiated, or whether that specialization might have a b member.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top