Is there any scope problem in this program?
#include<iostream>
using namespace std;
template<class Type>
class Base
{
public:
Type member;
Base(Type param): member(param){
}
};
template<class Type>
class Derived: public Base<Type>
{
public:
Derived(Type param):Base<Type>(param){
// ^
// |_______ Not writing Type here gives error, why?
}
void display()
{
cout << member; /** ERROR HERE **/
}
};
int main()
{
Derived<int> p(5);
p.display();
return 0;
}
I get error 'member' was not declared in this scope. How to fix the problems?
Your question is somewhat confusing. At first I thought you were asking about
base<Type>in the member initialization list, then I thought you were asking about accessingmember, then back to the first… Now I’m thinking you’re asking both, so I’ll answer both.When you use a class template’s name (
my_class_templ), it refers to the template, which is not a type. In order to use it as a type, you need to provide template parameters (my_class_templ<int>,my_class_templ<T>). So wherever a type name is needed (and that includes the base class names in an initialization list), you need to provide template parameters.You can omit the template parameter list for class templates names within the class template’s definition. For example, a copy constructor can be declared as
instead of
This is just a little syntactic sugar, allowing you to type less.
However, outside of the class templates definition, you need to explicitly spell out all the template parameters. This is also true for derived classes:
When your template is encountered first by the compiler, there’s only its definition and no instantiations have been seen by the compiler yet. The compiler doesn’t know whether, at a point of instantiation, there might be specializations of the template in scope or not. However, you could specialize your template for
Base<T>::memberto refer to something else or not to be defined entirely. (Say, a specializationBase<void>doesn’t have a data member.) Therefore, the compiler must not speculate about the members ofBase. Consequentially, they will not be looked up inDerived.The result of this is that, if you need to refer to one of the members of
Base, you need to tell the compiler that you expect aBase<T>to have such a member. This is done by fully qualifying its name:Base<Type>::member.