我们提供安全,免费的手游软件下载!
数据类型在程序设计中可能带来一些困扰,比如需要编写多个函数来处理不同类型的数据,增加了代码的冗余编写。解决这个问题的方法是引入类型占位符
T
,它可以代替具体的类型,从而简化代码。
int maxt(int, int);
double maxt(double, double);
通过引入类型占位符
T
,我们可以将函数声明简化为
T maxt(T,T);
。
在C++中,模板声明使用
template
的格式。其中,
template
是C++的模板声明关键字,尖括号内为模板参数列表,而
typename
是类型占位符的声明关键字。
template
T maxt(T x, T y){
return (x>y)? x: y;
}
在预编译阶段,当程序中调用函数模板时,编译器会用实际类型替换类型占位符生成实体函数。如果编译器可以从函数实参中推导出模板参数所需类型,那么可以不传入模板参数。
template
T maxt(T x, T y){
return (x>y)?x:y;
}
int main(int argc, char* argv[]){
// std::cout<< maxt(4,6)<< std::endl;
std::cout<< maxt(4,6)<< std::endl;
return 0;
}
在声明类时,使用
template
进行模板声明即可。如果在类模板外实现成员函数,则必须声明为函数模板。在调用时,需要在类名后使用尖括号传递具体类型。
template
class Circle{
public:
Circle(T r);
}
STL的模板编程对面向对象技术并不感兴趣,其认为类对数据的过度封装影响程序的执行效率。因此STL中使用大量没有访问权限的
struct
制作的类模板。
变量模板将模板扩展到变量。例如,
pi
的实现,当
T
为
double
时返回
3.14
,为
int
时返回
3
,为
string
时返回
"3.14"
或
"pi"
。
在C++11中,
auto
关键字用来推导变量的数据类型,如
auto a=100;
。而
decltype
的类型提示可用于推导
auto
类型的获取,尤其对于用户自定义类型或复杂类型。
auto
目前能力有限,只对系统的内置数据类型有效。对于用户自定义类型或复杂类型,只有当编译器取得足够经验后,才具备推导能力。
map>::const_iterator iter1=map1.begin();
auto iter2=map1.begin();
由于前一条语句告知了编译器
map1.begin()
的类型,在处理第二条语句时,便利用了记忆能力自动推导出
iter2
的类型。
decltype
表达式对推导函数返回值类型进行指导
C++11可以使用
decltype
对函数返回值的类型推导工作进行指导。这种使用
auto
作为函数返回值类型的称为auto返回值占位。
将
auto
看作数据类型,则
auto
也是一种泛型,只不过无须关键字
typename
声明。且实际类型不是由实参显式提供,而是根据类型操作相关历史记忆及应用程序提供的推导思路。
根据参数实参的性质,模板参数分为类型参数,非类型参数和模板定义型参数三种。
用关键字
typename
声明的参数。类型参数的类型实参包括系统内置的类型、用户自定义的数据类型、编译器刚学到的类模板实体以及由
typename
定义的类型别名。
C++允许在模板参数列表中定义普通变量或对象,如
template
。这种非类型参数在模板代码内是常量,不能修改。C++11支持非类型参数在定义时赋值,如
template
。
以类模板作为类模板参数,除了强调这个类型参数必须为类模板外,还强调该类模板的参数个数。
// 单模板参数的类模板
template
struct S_Tmp{};
// 多模板参数的类模板
template
struct D_Tmp{};
// 以单参数类模板作为参数的类模板
templateclass T>
struct MyTest{};
int main(){
MyTest tt1;
// MyTest tt1; // error
return 0;
}
编译器可以根据函数实参类型推导出模板形参所对应的实参,这种在调用函数模板时可以省略模板参数列表。因为函数调用语句中不提供函数返回值的类型信息,所以模板的返回值类型占位符必须与某个形参的占位符相同。
C++中,指针是一种数据类型,因此可作为模板实参。
可以在模板调用参数列表中使用修饰字
const
和
&
.
template
const T1& add(const T1& a, const T2& b){
return a;
}
数据类型的变化通常与业务逻辑无关。若有个别数据类型所对应的算法与其他类型对应的算法不同,这类算法就要单独编写。
如判断大小的函数,数值类型与字符串类型的比较算法是不一样的,应该分开实现。
template
T mymax(T a, T b){
return a>b?a:b;
}
template<>
char* mymax(char* a, char* b){
return (strcmp(a,b)<0)?b:a;
}
使用
template<>
是为了将其纳入
maxt
模板体系。
// 普通模板
template
struct Test{};
// 偏特化模板
template
struct Test{};
// 全特化模板
template<>
struct Test{};
编译器在匹配模板生成实体代码时的优先级为:特化模板(函数或类)>偏特化模板(类)>普通模板(函数或类)。
热门资讯