Content
Generic programming
Templates are a generic implementation, the generic is the template thought.
The essence of generics is the parameterization of types.
Function template
Function template
-
Basic grammar
template<class T> void function(T param1, T param2){ // ... }
template<typename T> void function(T param1, T param2){ // ... }
<class T>
And<typename T>
there is no difference.note!
template<class/typename T>
The declaration is only valid for the immediately following code block. -
Call method
-
Automatic type inference
int a; int b; function(a, b); // 没问题
int a; char b; function(a, b); // 报错
-
Show specified type
function<int>(a, b);
note! You must explicitly specify the type when you do not pass parameters, see the following example.
template<class T> void function(); int main(){ function();// 此时编译器无法自动推导,必须显式指定 }
-
-
The difference between function templates and ordinary functions
-
Type check
Template function type checking is stricter, and implicit conversion is not allowed. Examples:
template<class T> T templateFun(T param1, T param2); int function2(int param1, int param2); int main(){ int a; char b; // 调用模板函数不允许隐式转换 templateFun(a, c); // 报错 // 调用普通函数会发生隐式转换 function2(a, c); // 没问题 }
However, rvalue passing parameters allow implicit conversion, for example:
templateFun(1, 2); // 这是合法的
-
-
Call sequence
When overloading, call ordinary functions first
template<class T> T function(T param1, T param2); int function(int param1, int param2); int main(){ int a; int b; function(a, b); // 报错 }
If you want to force a template function to be called, you can explicitly specify empty template parameters
function<>(a, b);
If the template function has better parameter matching, the template function will be called
template<class T> T function(T param1, T param2); int function(int param1, int param2); int main(){ char a; char b; // 模板函数拥有更少的隐式转换,所以这里会匹配模板函数 function(a, b); }
-
Template functions allow overloading
template<class T> T function(T param1, T param2); template<class T> T function(T param1, T param2, T param3);
Template implementation mechanism
-
Function templates generate different functions through specific types
-
Second compilation:
First, check the syntax error of the function template and compile it. Then generate the corresponding template function and compile again.
Template reification
-
limitation
Function templates have certain limitations,
For example, arithmetic operations:
For arrays, there is no such syntax as arr1 + arr2.
If it is the object obj1 + obj2, you need to provide the corresponding overloaded function.
-
solve
Reification of the function template:
template<class T> void function(T a){ // ... 模板实现 } // 具体化 template<> void function<Type>(Type& a){ // ... 该模板函数的具体实现 }
That is, overloading for certain specific types.
Class template
-
Basic grammar
template<class type1, class type2> class Type { private: type1 __a; type2 __b; public: Type(type1 a, type2 b); }
note! Unlike function templates, you must explicitly specify the data type when instantiating an object.
Type<int, char> obj(1, '2');
-
Default parameters
The class template can use the default parameters of the type.
template<class type1, class type2 = char>
Of course, the function template can also use default parameters, but it's useless.
-
The rest is basically the same as the function template
Out-of-class implementation of class templates
Code:
template<class type1, class type2>
class Type {
private:
type1 __a;
type2 __b;
public:
Type(type1 a, type2 b);
void method(type1 a);
};
// 类外实现
template<class type1, class type2>
Type<type1, type2>::Type(type1 a, type2 b){
// ...
}
template<class type1, class type2>
void Type<type1, type2>::method(type1 a){
// ...
}
Sub-file preparation of class templates
The first thing to understand is that the method function of the class template will not be generated during the compilation phase, it is generated at runtime.
The general way we adjust the library is this:
#include"Type.h"
int main(){
Type obj;
obj.method();
}
An error will be reported, 无法解析的外部命令
that is, the corresponding function cannot be called during the linking phase.
Because no specific class template method function has been created at this time, of course I can't find it.
You can do this at this time:
#include"Type.cpp"
int main(){
Type obj;
obj.method();
}
However, under normal circumstances, we generally do not do sub-class template file written statements and will achieve in one .h
file.
Class template instance as function parameter
The data type inside the template instance is uncertain. If you want to pass it as a parameter, you can specify it directly in the parameter list or define it as a function template.
-
Specified type
Specify that only instances of this parameter type are allowed to be passed in:
void function(Type<int, string> obj);
-
Template function
Any instance of this template class is allowed to pass in:
template<class T1, class T2> void function(Type<T1, T2> obj);
-
Completely abstract
Needless to say, everyone knows this method:
template<class T> void function(T obj);
Class templates and friends
-
In-class implementation
note! Although it is implemented within a class, its scope is still global.
template<class type1, class type2> class Type { friend void function(Type<type1, type2>& obj){ // ... } private: type1 __a; type2 __b; };
-
Out-of-class implementation
First look at the error implementation:
template<class type1, class type2> class Type { friend void function(Type<type1, type2>& obj); private: type1 __a; type2 __b; }; template<class type1, class type2> void function(Type<type1, type2>& obj){ // ... }
If the function is called at this time, an error will be reported
无法解析的命令
, that is , the implementation of the function has not been found.Since the declaration inside the class is an ordinary function, and the implementation outside the class is a function template, when the parameter list is the same, the compiler will call the ordinary function first, which leads to the failure of the function implementation and link errors.
Two methods:
-
Declare template function
At this time, declare the friend declaration in the class as a template function.
template<class type1, class type2> class Type { template<class type1, class type2> friend void function(Type<type1, type2>& obj); private: type1 __a; type2 __b; }; template<class type1, class type2> void function(Type<type1, type2>& obj){ // ... }
-
Function template reification
Or first declare the template function, and then declare friends in the class, and make the parameters concrete.
// 声明 template<class type1, class type2> class Type<type1, type2> template<class type1, class type2> void function(Type<type1, type2>& obj); template<class type1, class type2> class Type { // 参数具体化声明 friend void function<>(Type<type1, type2>& obj); private: type1 __a; type2 __b; }; // 类外具体化实现 template<class type1, class type2> void function(Type<type1, type2>& obj){ // ... }
-
Inheritance in templates
Examples of errors:
No inheritance of abstract classes is allowed
template <class T>
class Base {
};
// 继承
class Type : public Base {
};
To inherit, it can be abstract or concrete.
-
Specify the template class to be inherited
template <class T> class Base { }; // 继承 class Type : public Base<int> { };
-
Abstract designation
template <class T> class Base { }; // 继承 template <class T> class Type : public Base<T> { };