9

i have an old codebase here, where they used protected member variables. Whether or not this is a good idea can be discussed. However, the code must have compiled fine with gcc3. I have a derived template class Bar that uses protected member x from class template Foo like so

template <class Something> class Foo {  
public:  
// stuff...  
protected:  
  some::type x;  
}

template <class Something> Bar : Foo<Something> {
public:
  void cleanup();
}

And in the method declaration of cleanup() there is something done with x

template <class Something> void Bar<Something>::cleanup() {
  doSomeThingCleanUpLike (x);
}

This does not work with gcc4, although it should have worked with gcc3. It works when I change it to

doSomeThingCleanUpLike (this->x);

Why is that the case?

GeeF
  • 707
  • 2
  • 8
  • 16
  • 1
    The term "template class" is often the source of confusion. The correct term is "class template", because the thing is a template for classes. It's not a class. I would edit your question but it's possibly one of the reasons that you got confused. – MSalters Oct 26 '09 at 14:41
  • 1
    Your function definition of "cleanup" isn't conformant. misses return type and template argments for "Bar". Sure that'S how it's in your code? – Johannes Schaub - litb Oct 26 '09 at 16:08
  • Thanks litb. I changed it. caffeine level wasn't high enough to spot it. Also changed to "class template". Whether its template class or class template shouldn't affect the problem though. The term is just informally used alot. – GeeF Oct 27 '09 at 09:03

2 Answers2

14

The expression x used in the derived class is, by the rules in the standard, not dependent on any template parameter of the derived class. Because of this, lookup happens in the context of the template definition and not at the point of use/instantiation. Even though the template base class of the template appears to be visible, because it is a template class the particular instantiation that might be used might involve specialized templates so the base class template definition cannot be used for name lookup.

By changing the expression to this->x you are making it a dependent expression (this in a class template always depends on the template parameters). This means that lookup will occur in the instantiation context at which point the base class is fully known and its members are visible.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
6

When you're defining the derived template, the compiler only knows the base template class' name but not its details, so compiler doesn't know the derived class has an inherited member. In order to tell the compiler of the member's existence, use this->, just like you did.

Actually, it is a duplicate of this question.

Community
  • 1
  • 1
Igor
  • 26,650
  • 27
  • 89
  • 114