I am new to C++. During my learning phase I encountered with below issue.
I am trying to derive a class stack
from a class template Queue
.
Compiler thr
The reason is that inside a template, two-phase name lookup rules apply:
Names which do not depend on template parameters are looked up (=resolved) when the template is defined (=parsed).
Names which do depend on template parameters are looked up when the template is instantiated (when you provide the template arguments).
Base classes which depend on template parameters are only searched during name lookup at instantiation time.
The reason for this two-phase lookup is that until the template arguments are known, the compiler cannot know what the definition of the base class (or other dependent construct) will be. Remember that template specialisation exists.
You need to somehow tell the compiler that the name b
is dependent. You basically have three ways to do that:
Prefix the name with this->
; since you're in a class template, all your members depend on template parameters implicitly:
this->b = a;
Use full qualification for the name. This will make the dependency on template parameters explicit:
Queue<T>::b = a;
Put a using
declaration into your class to inform the compiler that the name comes from a dependent base class:
template <class T>
class stack :public Queue<T> // Derived class
{
protected:
using Queue<T>::b;
public:
stack():Queue<T>()
{
b=a;
}
void pop()
{
b--;
}
};
In a template definition, unqualified names will no longer find members of a dependent base (as specified by [temp.dep]/3 in the C++ standard). For example, You must make the names dependent, e.g. by prefixing them with this->.
gcc-problem-using-a-member-of-a-base-class-that-depends-on-a-template-argument
And yes, it can be valid in VS.
Because the base class is a template, whose instantiation depends on a template parameter of the derived class, and you're trying to name a member of the base class, two-phase lookup mandates that you write this->b
, not b
.
(And that default constructor call is not needed.)
stack()
{
this->b = this->a;
}
void pop()
{
this->b--;
}
Welcome to C++… :P
[C++11: 14.6.2/3]:
In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. [..]