在C语言和C++98中,auto 关键字用于修饰变量(自动存储的局部变量)。
在C++11中,赋予了auto 全新的含义,不再用于修饰的变量,而是作为一个类型指示符,指示编译器在编译时推导auto声明的变量的数据类型。
在Linux 平台下,编译需要加-std=c++11 参数。
- #include
- using namespace std;
-
-
- // 如果初始化变量的时候不定义类型,那么会使用auto关键字
- // 根据变量赋值,自动推导出相关类型
- int main() {
- auto a = 3; cout << "a=" << a << endl;
- auto b = 3.3; cout << "b=" << b << endl;
- auto c = "鲁班"; cout << "c =" << c << endl;
- system("Pause");
- }

注意事项:


auto关键字可以计算两个不同类型的值
- #include
- using namespace std;
-
- template<typename T1, typename T2>
- void func(T1 x, T2 y) {
-
- auto tmp = x + y;
- cout << tmp << endl;
- }
-
- int main() {
- short a = 1;
- char b = 2;
- func(a, b);
- system("Pause");
- return 0;
- }
先看一段代码:如果我们需要更换两个变量的值,根据变量值的不同,需要不断的重载Swap函数,函数中的tmp变量类型也会改变,其他地方都一样。
- #include
- using namespace std;
-
- // 交换两int值
- void Swap(int &a ,int &b) {
- int tmp = a;
- b = a;
- a = tmp;
- }
-
- // 交换两double值
- void Swap(double& a, double& b) {
- double tmp = a;
- b = a;
- a = tmp;
- }
-
- // 交换两字符串值
- void Swap(string& a, string& b) {
- string tmp = a;
- b = a;
- a = tmp;
- }
-
-
- int mian() {
-
- }
为了避免这种麻烦,利用模型来生成相应的函数代码,即函数模板:
创建交换两个变量的函数模板:
- #include
- using namespace std;
-
- // 创建一个函数模板,交换两个变量的值
- // 定义模板,这里anytype可以随便取名,但是需要注意和下面一致
- // 函数模板用typename 类模板用 class
- template <typename T>
- void Swap(T& a, T& b) {
- T tmp = a;
- a = b;
- b = tmp;
- }
-
-
- int main() {
- int a = 1, b = 2;
- cout << a << b << endl;
- Swap(a, b);
- cout << a << b << endl;
- system("Pause");
- return 0;
-
- }
注意事项:
- #include
- using namespace std;
-
- class Fruit {
- public:
- // 构造函数
- template <typename T>
- Fruit(T a) {
- cout << "a=" << a << endl;
- }
-
- // 用到模板的地方在上面都要加这一句
- template <typename T1,typename T2>
- void show(T1 b,T2 c) {
- cout << "b=" << b << endl;
- cout << "c=" << c << endl;
- }
- };
-
- int main() {
- Fruit apple("烟台红苹果");
- apple.show("真的甜","好吃");
- system("Pause");
- return 0;
-
- }

语法:
template<>void 函数模板名<数据类型>(参数列表)
template<>void 函数模板名(参数列表)
{
// 函数体
}
- #include
- using namespace std;
-
- class Fruit {
- public:
- // 构造函数
- Fruit(const string& f_name,int f_gram) {
- m_gram = f_gram;
- m_name = f_name;
- }
-
-
- void show_gram() {
- cout << this->m_name << this->m_gram << endl;
- }
-
- string m_name;
- int m_gram;
- };
-
- // 函数模板
- template<typename T>
- void Swap(T& a, T& b) {
- T tmp = a;
- a = b;
- b = tmp;
- cout << "调用了Swap(T& a, T&b)" << endl;
- }
-
- //具体化函数
- template<>void Swap(Fruit& f1, Fruit& f2) {
- int tmp = f1.m_gram;
- f1.m_gram = f2.m_gram;
- f2.m_gram = tmp;
- cout << "调用了Swap(Fruit& f1, Fruit& f2)" << endl;
- }
-
- int main() {
- Fruit apple("苹果", 12), orange("橘子", 55);
- apple.show_gram();
- orange.show_gram();
- Swap(apple, orange);
- apple.show_gram();
- orange.show_gram();
- system("Pause");
- return 0;
-
- }

函数模板的定义和声明都是在头文件中,普通函数和函数模板的具体化版本是分开的。
main.cpp
- #include
- #include"public.h"
- using namespace std;
-
- int main() {
- Swap(1, 1); // 使用普通函数
- Swap('c', 'd'); // 使用函数模板
- Swap<>(1, 1); // 使用函数模板具体化版本
- system("Pause");
- return 0;
- }
头文件public.h:
- #pragma once
- #include
- using namespace std;
-
- void Swap(int a, int b); // 普通函数
-
- template<typename T> // 函数模板
- void Swap(T a, T b) {
- cout << "使用了函数模板" << endl;
- }
-
- template<>
- void Swap(int a, int b); // 函数模板具体化版本
源文件public.cpp
- #include "public.h"
-
- void Swap(int a, int b) {
- cout << "使用了普通函数" << endl;
- }
-
- template<>
- void Swap(int a, int b) {
- cout << "使用了具体化的函数模板" << endl;
- }
template <class T>
class 类模板名
{
类的定义
}
- #include
- using namespace std;
-
- template<class T1,class T2>
- class AA {
- public:
- T1 m_a;
- T2 m_b;
- AA(T1 a, T2 b) :m_a(a), m_b(b){}
-
- //构造函数
- AA() {}
-
- // 可以用于成员函数的返回值
- // 即a是什么类型,这里geta返回的也是什么类型
- T1 geta() {
- T1 num = 2; // 这里也可以定义一个和a相同类型的与a相加
- return m_a + num;
- }
- T2 getb() {
- T1 num = 2;
- return m_b;
- }
-
- };
-
-
-
- int main() {
- AA<int, double>a; // 用模板类AA创建对象
- a.m_a = 2;
- a.m_b = 3;
- cout << "a.geta()=" << a.geta() << endl;
- cout << "a.getb()=" << a.getb() << endl;
- system("Pause");
- return 0;
- }

可以用new创建模板类对象:main函数这么写
- int main() {
- AA<int, double>*a=new AA<int, double>(1,2); // 用模板类AA创建对象
-
- cout << "a.geta()=" << a->geta() << endl;
- cout << "a.getb()=" << a->geta() << endl;
-
- delete a;
- system("Pause");
- return 0;
- }
- #include
- using namespace std;
-
- //类模板
- template<class T1,class T2>
- class AA {
- T1 mx;
- T2 my;
-
- AA(const T1 x, const T2 y) :mx(x), my(y) { cout << "类模板,构造函数" << endl; }
- void show()const;//类内声明,类外实现
- };
-
- // 成员函数类外实现
- template<class T1,class T2>
- void AA
::show()const { - cout << "类模板:x=" << mx << ",y=" << my << endl;
- };
-
- //类模板完全具体化
- template<>class AA<int, string> {
- public:
- int mx;
- string my;
-
- AA(const int x, const string y) :mx(x), my(y) { cout << "完全具体化:构造函数" << endl; };
- void show()const;
- };
-
- void AA<int, string>::show()const {
- cout << "完全具体化x=" << mx << ",y=" << my << endl;
- };
-
- //类模板部分显示具体化
- template<class T1>
- class AA
{ // T1通用,string具体 - public:
- T1 mx;
- string my;
-
- AA(T1 x, const string y) :mx(x), my(y) { cout << "部分具体化:构造函数 " << endl; };
- void show()const {
- cout << "部分具体化x=" << mx << ",y=" << my << endl;
- };
- };
-
- int main() {
- //具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类
- AA<int, string>aa(22, "光头强");
- aa.show();
- system("Pause");
- return 0;
- }

模板类继承普通类(常见)
普通类继承模板类的实例版本
普通类继承模板类(常见)
模板类继承模板类
模板类继承模板参数给出的基类(不能是模板类)
下面演示第一种:模板类继承普通类
- #include
- using namespace std;
-
- class AA { // 普通类AA
- public:
- int m_a;
- AA(int a) :m_a(a) { cout << "调用AA构造函数" << endl; }
- void func1() { cout << "调用func1函数:m_a=" << m_a << endl; }
-
- };
-
- template<class T1,class T2>
- class BB:public AA // 模板类BB
- {
- public:
- T1 m_x;
- T2 m_y;
- BB(const T1 x, const T2 y,int a):AA(a),m_x(x), m_y(y) { cout << "调用BB构造函数" << endl; }
- void func2() { cout << "调用func2函数,x+y=" << m_x <<",m_y=" << m_y << endl; }
-
-
- };
-
- int main() {
-
- BB<int, string>bb(22, "光头强", 6666);
- bb.func1();
- cout << "--------------------" << endl;
- bb.func2();
- system("Pause");
- return 0;
- }

第三种情况:普通类继承模板类:
- #include
- using namespace std;
-
-
-
- template<class T1,class T2>
- class BB // 模板类BB
- {
- public:
- T1 m_x;
- T2 m_y;
- BB(const T1 x, const T2 y):m_x(x), m_y(y) { cout << "调用BB构造函数" << endl; }
- void func2() { cout << "调用func2函数,x+y=" << m_x <<",m_y=" << m_y << endl; }
-
-
- };
-
- template<class T1, class T2>
- class AA:public BB
{ // 普通类AA - public:
- int m_a;
- AA(int a,const T1 x,const T2 y) :BB
(x,y),m_a(a) { cout << "调用AA构造函数" << endl; } - void func1() { cout << "调用func1函数:m_a=" << m_a << endl; }
-
- };
-
- int main() {
-
- AA<int, string>aa(1,22, "光头强");
- aa.func1();
- cout << "--------------------" << endl;
- aa.func2();
- system("Pause");
- return 0;
- }

- #include
- using namespace std;
-
- template<class T1,class T2>
- class AA {
- public:
- T1 m_x;
- T2 m_y;
-
- AA(const T1 x,const T2 y):m_x(x),m_y(y){}
- void show() { cout << "m_x=" << m_x << " m_y=" << m_y << endl; }
-
- template<class T> // 类模板
- class BB
- {
- public:
- T m_a;
- T1 m_b;
- BB(){}
- void show() { cout << "m_a=" << m_a << " m_b=" << m_b << endl; }
- };
-
- BB
bb; // bb就是类模板AA的一个成员 -
- //函数模板
- template<typename TF>
- void showf(TF tt) { cout << "tt=" << tt << endl; }
-
- };
-
- int main() {
- AA<int, string>a(22, "光头强");
- a.show();
- a.bb.m_a = "熊大";
- a.bb.show();
- a.showf("看我大卫天龙");
-
-
- system("pause");
- return 0;
- }
