在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
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
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 Fruit(T a) {cout << "a=" << a << endl;}// 用到模板的地方在上面都要加这一句template 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
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 // 函数模板
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 类模板名
{
类的定义
}
#include
using namespace std;template
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() {AAa; // 用模板类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*a=new AA(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 AA {T1 mx;T2 my;AA(const T1 x, const T2 y) :mx(x), my(y) { cout << "类模板,构造函数" << endl; }void show()const;//类内声明,类外实现
};// 成员函数类外实现
template
void AA::show()const {cout << "类模板:x=" << mx << ",y=" << my << endl;
};//类模板完全具体化
template<>class AA {
public:int mx;string my;AA(const int x, const string y) :mx(x), my(y) { cout << "完全具体化:构造函数" << endl; };void show()const;
};void AA::show()const {cout << "完全具体化x=" << mx << ",y=" << my << endl;
};//类模板部分显示具体化
template
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() {//具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类AAaa(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 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() {BBbb(22, "光头强", 6666);bb.func1();cout << "--------------------" << endl;bb.func2();system("Pause");return 0;
}
第三种情况:普通类继承模板类:
#include
using namespace std;template
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 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() {AAaa(1,22, "光头强");aa.func1();cout << "--------------------" << endl;aa.func2();system("Pause");return 0;
}
#include
using namespace std;template
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 BB{public:T m_a;T1 m_b;BB(){}void show() { cout << "m_a=" << m_a << " m_b=" << m_b << endl; }};BBbb; // bb就是类模板AA的一个成员//函数模板templatevoid showf(TF tt) { cout << "tt=" << tt << endl; }};int main() {AAa(22, "光头强");a.show();a.bb.m_a = "熊大";a.bb.show();a.showf("看我大卫天龙");system("pause");return 0;
}