Chapter 4 templates and generics - Section 4.4 of learning notes for C + + new classic courses

The knowledge points reviewed in this section are member function template, explicit instantiation and declaration.

The knowledge summarized today is divided into the following three points:

(1) Member function template
(2) Member function template of common class and template class
(3) Template explicit instantiation, template declaration

(1) Member function template:

         Whether it is a normal class or a template class, its member functions can become a function template. so, if the member function of a class is a function template, the function template is called "member function template".

(Note: virtual functions cannot become templates!)

class Person {
public:
	//...
	template<typename T>
	virtual void func(T t) {//Wrong! virtual is not allowed in the declaration of function template!
		cout << t << endl;
	}
	//...
};

Operation results:

(2) Member function template of common class and template class         

a) Member function template of common class:

(a common class whose member function is a function template)

See the following example codes:

class A {General class
public:
	template<typename T>
	void mytfunc(T tmpt) {//Member function template = = > the member function of a common class is a function template
		cout << tmpt << endl;
	}
};
int main(void) {
	A a;
	a.mytfunc(3);//Note: only when the compiler encounters this code will it instantiate a special version of the member function
	/*
	==> At this point, the compiler generates a special version of the member function myfunc:
		void mytfunc(int tmpt){
			cout<< tmpt <<endl;
		}
		 (Note: here, the compiler automatically infers that the parameter we pass in is an int type)
	*/
	//==> result: 3
	a.mytfunc<double>(1388.8);
	/*
	==> At this point, the compiler generates a special version of the member function myfunc:
		void mytfunc(double tmpt){
			cout<< tmpt <<endl;
		}
	 (Note: Here we specify the parameter to the compiler (which is a double type)
	*/
	//==> result: 1388.8
	return 0;
}

 

a) Member function template of template class:

(a template class whose member function is a function template)

         Note ①: when need defines its member function template outside the definition of the template class, it should be written as follows:

         Format:

template<Template parameter list 1 of the whole template class>
template<Template parameter list 2 of a member function template>
retName className<List 1>::funcName(Params){
    //...
}

         Note ②: only when the member functions of the class template (including ordinary member functions and member function templates) are called (that is, when the calling code for the member function / function template appears in the program), the compiler will help us instantiate the specific implementation code of these functions. If a function in the template class has never been called in the program, the compiler will not instantiate (generate) the specific code of the member function.

See the following example codes:

template<typename C>
class AA {
public:
	C m_ic;
public:
	//Define a constructor template
	template<typename T1,typename T2>//Note: the template parameters T1 and T2 have nothing to do with the template parameter C of the whole class!
	AA(T1 v1, T2 v2);
	template<typename T3, typename T4>
	void func(T3 v3, T4 v4);
    template<typename T5>
    void func2(T5 tmpt){ cout<<"this is func2!"<<endl; }
    void func3(){ cout<<"this is func3!"<<endl; }
    
};

template<typename C> //Write the parameter list of the whole class template first
template<typename T1, typename T2>//Then write the parameter list of the member function template in this class
AA<C>::AA(T1 v1, T2 v2) {
	cout << "this is constructor ~ yeah" << endl;
}
template<typename C> //Write the parameter list of the whole class template first
template<typename T3, typename T4> //Then write the parameter list of the member function template in this class
void AA<C>::func(T3 v3, T4 v4) {
	cout << "v3 = " << v3 << " v4 = " << v4 << endl;
}
int main(void){
	AA<float> aa(1,2);
	//Since the constructor is automatically called by the compiler for us (and it is automatically inferred for us that the parameters passed into the constructor are 2 int parameters)
	//Therefore, we must not call the constructor by specifying template parameters
	aa.func(3, 4);
	aa.func<double,double>(33.3, 44.4);//However, for general member functions, we can specify template parameters to call it!
    return 0;
}

         Explanation: in the above code, only the func() function is called for the construction of the member function in the template Class AA, that is, the compiler instantiates the specific implementation code of the two member functions for us:

AA Code in constructor for: cout << "this is constructor ~ yeah" << endl;Instantiated by the compiler
func()Code in: cout << "v3 = " << v3 << " v4 = " << v4 << endl;Instantiated by the compiler

func2() and func3() are not instantiated by the compiler:

func2()Code in:{ cout<<"this is func3!"<<endl; }Not instantiated by compiler!
func3()Code in:{ cout<<"this is func2!"<<endl; }Not instantiated by compiler!

(3) Template explicit instantiation, template declaration:

Unfinished to be continued~

Tags: C++ Back-end

Posted on Sun, 28 Nov 2021 23:43:29 -0500 by deezzer