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

10

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
  • 362,284
  • 104
  • 897
  • 1,065
  • 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