3

I am having an issue with inheritance. I created this example to show more or less my issue. The thing is that if I publicly derive from class that publicly derives from a class then I must have access to protected members in the original class all the way. However this doesn't seem to be the case when I'm using templates.

In fact, the example below complains on the line where 'n++;' saying that 'n' was not declared in the scope. However, if I do it without the templates. The code compiles just fine. What is going on?

#include<iostream>
template<typename T> 
class base{
 protected:
    T n;
 public:
    T getn();
    base();
};

template<typename T>  
T base<T>::getn(){
   return n; 
}

template<typename T> 
base<T>::base(){
   n = 8; 
}

template<typename T> 
class daddy: public base<T>{
protected: 
public:
};

template<typename T>
class granny: public daddy<T>{
protected:
public:
    T plusone();
};

template<typename T> 
T granny<T>::plusone(){ 
    //this->n = this->n + 1;
   n++;
   return n;
}

int main(){
   granny<int> oldmommy;

   int su = oldmommy.getn();   
   std::cout << su << std::endl;
   su = oldmommy.plusone();
   std::cout << "plusone" << su << std::endl;
   return 0;
}

Btw. Tell me if I should post the code with no templates to compare..

Wilmer E. Henao
  • 4,094
  • 2
  • 31
  • 39

2 Answers2

3

A quick fix is to apply this before the variable:

 this->n = this->n + 1;
 return this->n;

The reason is that the compiler makes no assumptions about template base class members (n in this case, which is dependent on the type T) in case there is a partial specialization of the base class that does not include some of these members.

taocp
  • 23,276
  • 10
  • 49
  • 62
  • Ok. That works. By the way, I'm not a regular user of this site. how does it work here. Do I type [solved] in the title? – Wilmer E. Henao Apr 09 '13 at 02:04
  • @WilmerEHenaoH there is a "\/" sign along with the answer, if you accept one's answer, you just click that sign, meaning that the answer solves your question. However, others can still post their answers if they want. – taocp Apr 09 '13 at 02:07
2

n is a dependent name here. You must explicitly indicate where that n comes from, otherwise the compiler doesn't know which n you're referring to(note that there could be some base specialization which doesn't have a member named n).

You can achieve this by using:

this->n;

Or:

base<T>::n;

Instead of n in your code.

Community
  • 1
  • 1
mfontanini
  • 21,410
  • 4
  • 65
  • 73