When compiling the template, the compiler will resolve the name encountered in two phases, the first phase parsing does not depend on the name of the template parameter, the second phase resolution depends on the name of the template parameter, and here is a simple example to illustrate this point:
Template<class t> class X {public:typedef int E;}; typedef double E;TEMPLATE<CLASS T> class y:public x<t> {public:e f () {}};
This example defines two class templates, where Y is derived from X, in x we give int an alias E, and then in the global scope to double also take an alias E, in Y has a function f (), its return value type E, then this e is double, or int? The result is a double because f () does not depend on the template parameter T, so it is parsed at the first stage, and its base class x< T> is parsed in the second phase, so when parsing f (), you can only see the typedef in the global scope, double E. If you have any questions in mind, we can look at the non-template class situation:
Class X {public:typedef int E;}; typedef double E;class Y:public X {public:e f () {}};int main () {Y Y;cout<<typeid (Y.F ()). Name () <<endl;return 0 ;}
This example is a common class, and with the test of the main function, you can see that the return type of f () becomes int. Now let's look at an example:
void G () {cout<< "gobal::g ()" <<endl;} Template<class t> class X {public:typedef int e;void g () {cout<< ' x::g () ' <<endl;}}; typedef double E;TEMPLATE<CLASS T> class y:public x<t> {public:e f () {g (); This->g ();}}; int main () {y<char> Y;cout<<typeid (Y.F ()). Name () <<endl;y.f (); return 0;}
In this example, we first define a global function g (), then define the class template X, define a member function g () in X, the class template y still inherits from X, and "G ()" in f () in Y, then the same g () is called in both ways? The answer is: No, the first method calls the global G (), and the second method calls the base class G (), because when the compiler encounters the first method of G (), it is found that it does not appear to rely on the template parameters, so it is not dependent on the template parameters, so in the first phase of the parsing, at this time X <T> has not yet been parsed, so G () is the global G (), when called by the second method, it is indicated by the this pointer that G () is dependent on the current object and depends on the template parameters, thus parsing in the second phase, when the base class will be parsed before Y, so This-->g ( ) called the base class's G (). Again, we can look at the common class situation:
void G () {cout<< "gobal::g ()" <<endl;} Template<class t> class X {public:typedef int e;void g () {cout<< ' x::g () ' <<endl;}}; typedef double E;TEMPLATE<CLASS T> class y:public x<t> {public:e f () {g (); This->g ();}}; int main () {y<char> Y;cout<<typeid (Y.F ()). Name () <<endl;y.f (); return 0;}
The result is that the G () of the base class X is called twice, and this example tells us that, in a class template, if you need to use a member function, you need to specify it through the this pointer, rather than omitting to the this pointer as in a normal class, in fact, without the this pointer, without the global function g () , the following error will appear at compile time:
Error:there is no arguments to ' g ' this depend on a template parameter, so a declaration of ' G ' must is available.
C + + templates: Name lookup