9

Possible Duplicates:
[FAQ] Why doesn't a derived template class have access to a base template class' identifiers? Problem with protected fields in base class in c++
cannot access data member in a class template

Following code gives me compilation error. What is wrong?

struct Base {
   int amount;
};

template<class T> struct D1 : public Base {
};

template<class T>
struct D2 : D1<T> {
  void foo() { amount=amount*2; /* I am trying to access base class data member */ };
};

int main() {
  D2<int> data;
};


test.cpp: In member function 'void D2<T>::foo()':
test.cpp:11: error: 'amount' was not declared in this scope

How to fix this?

thanks

Community
  • 1
  • 1
anon
  • 93
  • 1
  • 1
  • 3
  • I've seen this question several times before but I can't find a link. – Chris Lutz Feb 07 '11 at 08:46
  • Found one, though if someone can find one with a better question that'd be great: [Problem with protected fields in base class in c++](http://stackoverflow.com/questions/1813671/problem-with-protected-fields-in-base-class-in-c) – Chris Lutz Feb 07 '11 at 08:47
  • 2
    @Chris: Here's a [duplicate](http://stackoverflow.com/questions/4210108/cannot-access-data-member-in-a-class-template), and here's a [lengthy explanation](http://stackoverflow.com/questions/4643074/why-do-i-have-to-access-template-base-class-members-through-the-this-pointer). – GManNickG Feb 07 '11 at 08:47
  • Did you notice that D2 inherits privately from D1? Not the cause of the error, but probably an additional mistake. – Gorpik Feb 07 '11 at 08:47
  • 3
    @Gorpik- D2 actually inherits publicly from D1 because because it's a struct and the default inheritance mode for structs is public. – templatetypedef Feb 07 '11 at 08:48
  • Everybody vote for @GMan's duplicate suggestion, it's a better question to direct people to than mine is. – Chris Lutz Feb 07 '11 at 08:50
  • @templatetypedef: You are right, I stand corrected. – Gorpik Feb 07 '11 at 08:53
  • @GMan: I've put the current FAQ entry regarding this issue atop of the list of dupes. If one of the other questions seems a better fit as an FAQ, feel free to make it an FAQ (be sure to remove the current one, though) and undo my change. – sbi Feb 07 '11 at 16:14

1 Answers1

9

The problem here has to do with how names are looked up in template classes that inherit from template base classes. The actual rules behind it are pretty arcane and I don't know them off the top of my head; I usually have to consult a reference to learn precisely why this doesn't work.

The way to fix this is to explicitly prefix the member you're accessing with this->:

void foo() { 
    this->amount = this->amount * 2; // Or: this->amount *= 2;
}

This gives the compiler an unambiguous hint about where the name amount comes from and should resolve the compiler error.

If someone wants to give a more detailed description of why this error occurs I'd love to see a good explanation.

templatetypedef
  • 345,949
  • 98
  • 857
  • 1,030
  • 2
    The reason for the error is that the compiler makes no assumptions about template base class members in case there is a partial specialisation of the base class that does not include some of these members. – Gorpik Feb 07 '11 at 08:50
  • 1
    According to [this](http://www.hackcraft.net/cpp/templateInheritance/): "An interesting thing to note about base is that none of it’s member functions are created until after the type T is." So the compiler may not know at definition time about any of the members, not just the functions. – jswolf19 Feb 07 '11 at 09:02