C ++ template: Name Search
During template compilation, the compiler will parse the names encountered in two phases. The first phase of parsing does not depend on the template parameter name, and the second stage of parsing depends on the template parameter name, the following is a simple example:
template
class X {public:typedef int E;};typedef double E;template
class Y : public X
{public:E f() {}};
In this example, two class templates are defined. Y is derived from X. In X, we give int an alias E, then, in the global scope, double is also given an alias E. In Y, there is a function f (), and its return value type is E. Then, is this E double, or int? The result is double. Because f () does not depend on the template parameter T, it will be parsed in the first stage, and its base class X <. t> it will be parsed in the second stage. Therefore, when parsing f (), you can only see typedef double E in the global scope. If you have any questions, let's look at the situation of non-template classes:
Class X {public: typedef int E ;}; typedef double E; class Y: public X {public: E f () {}}; int main () {Y y Y; cout <
In this example, it is a common class. Through the test of the main function, we can see that the return type of f () has changed to int. Next, let's look at an example:
Void g () {cout <"gobal: g ()" <
Class X {public: typedef int E; void g () {cout <"X: g ()" <
Class Y: public X
{Public: E f () {g (); this-> g () ;}}; int main () {Y
Y; cout <
In this example, we first define a global function g (), then define the class template X, and define a member function g () in X. The class template Y still inherits from X, in f () of Y, "g () is called in two ways". Are the two methods called in the same g? The answer is: No. The first method calls the global g (), while the second method calls the g () of the base class (), the reason is that when the compiler encounters the first method g (), it finds that it does not show that it depends on template parameters, so it is considered that it does not depend on template parameters, therefore, the first phase is parsed.
Not resolved yet, so g () is the global g (). When calling the second method, use the this pointer to indicate that g () depends on the current object, it depends on the template parameters, so it will be parsed in the second stage. At that time, the base class will be parsed before Y, so this --> g () calls the g () of the base class (). Similarly, we can look at the situation of common classes:
Void g () {cout <"gobal: g ()" <
Class X {public: typedef int E; void g () {cout <"X: g ()" <
Class Y: public X
{Public: E f () {g (); this-> g () ;}}; int main () {Y
Y; cout <
The result shows that the g () of the base class X is called twice. this example tells us that in the class template, if you need to use a member function, you must use the this pointer to specify it, instead, the this pointer cannot be omitted as it is in a common class. In fact, if you do not use this pointer to specify it without the global function g (), the following error will occur during compilation:
Error: there are no arguments to 'G' that depend on a template parameter, so a declaration of 'g' must be available.