C++模板

模板:将类型当作未知量,可以忽略类型的影响,从而减少类型对代码的影响

函数模板:

#include<iostream>
#include<string>
using namespace  std;
//单个位置类型
template<typename _Ty> //_Ty可以修改为任意
_Ty Max(_Ty a, _Ty b)
{


    return a > b ? a : b;//经典的冒号问号表达式
}
//多个未知类型
template<typename _Ty1, typename _Ty2 >
void print(_Ty1 a, _Ty2 b)
{

    cout << a << endl;
    cout << b << endl;
}
int main() 
{  
   int a=Max(1,3);
   cout << a << endl;
    print(1,2);
    print(1.1, 2.1);


}

调用方式:隐式调用 显式调用

函数模板两种形态 普通函数当作模板,类的成员函数当作模板

函数模板的特殊写法:缺省写法,存在常量的写法

#include<iostream>
#include<string>
using namespace std;
template <typename _Ty>		//告诉编译器 下面代码用到一个位置类型叫做_Ty
_Ty Max(_Ty a, _Ty b)
{
    return a > b ? a : b;
}
//在新标准中 typename_Ty 可以写成class _Ty
template <class _Ty1, class _Ty2>
void print(_Ty1 one, _Ty2 two)
{
    cout << one << endl;
    cout << two << endl;
}
class Fox
{
public:
    template<class _Ty1>
    void  printf(_Ty1 data=)
    {
        cout << data << endl;
    }
    template<class _Ty1>
    void printfdata(_Ty1 data);//类中声明
protected:
    string  name;
    int age;
};
//在类外实现不能省略template
template<class _Ty1>
void Fox::printfdata(_Ty1 data)
{
    cout << data << endl;
}
//缺省写法
template <class _Ty1,class _Ty2=int >
void printf(_Ty1 a, _Ty2 b)
{
    cout << a << b << endl;
}
//常量写法
template <class _Ty1, size_t size=3 >//size_t无符号整形
void printArray(_Ty1 array)
{
    for (int i = 0; i < size; i++) {
        cout << array[i];
    }
    cout << endl;

}
void test() //测试函数

{

    printf("狐狸",3544);//隐式调用
    printf<string>("狐狸", 123);//显式调用,虽有两个未知参数,由于缺省写法,可以少写一个类型,但参数个数不能少
    int array[3] = { 0 };
    //没有缺省必须显示调用
    printArray<int*, 3>(array);
    //有了缺省之后可以隐式调用
    printArray(array);
    //函数模板无法传入变量,函数参数可以
   
}

int main() 
{


    //隐式调用
    cout << Max(1, 2) << endl;
    cout << Max("狐狸1", "狐狸2") << endl;
    cout << Max(1.1, 2.3) << endl;
    //显示调用
    cout << Max<string>("狐狸23", "狐狸24") << endl;
    print<string, string>("1", "2");
    print<string, int>("1", 1234);
    //类中的成员函数是函数模板
    Fox fox;
    //隐式调用
    fox.printf(123);
    //显示调用
    fox.printf<string>("ILoveyou");
    //隐式调用
    fox.printfdata(12344);


    return 0;
}

类模板:被template修饰就是一个模板类

类模板不是一个实际类,所有用到类名的地方都需要类名<未知类型>方式使用

多文件中,类模板 中的声明和实现一定在一起的,不能分开写。

  

#include<iostream>
#include<string>
using namespace std;
template <class _Ty>
class Fox
{
public:
    Fox() {}
    Fox(string name) :name(name) {}
    void print();
protected:
    string name;
};
//在类外实现

template <class _Ty>
void Fox<_Ty>::print()
{
    cout << "类模板" << endl;
}
//包括继承中 也要写类名<未知类型>Fox
template<class _Ty>
class Foxson :public Fox<_Ty>
{
public:
    Foxson(string name) :Fox<_Ty>(name)//包括构造函数
    {

    }
protected:

};
//多个未知类型的模板类
template<class _Ty1, class _Ty2>
class Data
{
public:
    Data(_Ty1 one, _Ty2 two) :one(one), two(two) {}
    void print();
protected:
    _Ty1 one;
    _Ty2 two;
};
template<class _Ty2,class _Ty1>
void Data<_Ty2, _Ty1>::print()
{
    cout << one << endl;
    cout << two << endl;
}

int main() 
{
    //类模板必须显式调用
    Foxson<int> foxson("狐狸123");
    Data<string, int>data("狐狸1",3);
    data.print();
    foxson.print();
    return 0;
}

自定义类型当作模板参数

自定义类型也是模板,模板传入自定义,关键点在于重载运算符

#include<iostream>
#include<string>
using namespace std;
template <class _Ty>
class Fox
{
public:
    Fox() {}
    Fox(string name,int age) :name(name),age(age) {}
    void print();
    friend ostream& operator<<(ostream& out, const Fox& fox) //运算符重载
    {
        out << fox.name << " " << fox.age;
        return out;
    }
protected:
    string name;
    int age;
};
template <class _Ty>
void print(_Ty one)
{
    cout << one << endl;
}
int main() 
{
    print(53);

    Fox<string> fox("狐狸1",13);

    print(fox);
    return 0;
}
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
	Fox(string name, int age) :name(name), age(age) {}
	friend ostream& operator<<(ostream& out, const Fox& fox)//需要运算符重载
	{
		out << fox.name << " " << fox.age;
		return out;
	}
protected:
	string name;
	int age;
};
template <class _Ty>
class Node
{
public:
	Node(_Ty data, Node<_Ty>* next) :data(data), next(next) {}
	_Ty getData()
	{
		return data;
	}
	Node<_Ty>* getNext()
	{
		return next;
	}
protected:
	_Ty data;
	Node<_Ty>* next;
};
template <class _Ty>
class List
{
public:
	List()
	{
		headNode = nullptr;
	}
	void insertList(_Ty data)
	{
		headNode = new Node<_Ty>(data, headNode);
	}
	void printList()
	{
		Node<_Ty>* pmove = headNode;
		while (pmove != nullptr)
		{
			cout << pmove->getData() << endl;
			pmove = pmove->getNext();
		}
		cout << endl;
	}
protected:
	Node<_Ty>* headNode;
};
int main() 
{
	List<Fox> list;
	list.insertList(Fox("狐狸1", 18));
	list.insertList(Fox("狐狸2", 13));
	list.insertList(Fox("狐狸3", 21));
	//将自定义类型当作数据存放进链表
	list.printList();
	//通过运算符重载输出数据
}

 模板嵌套:

#include <iostream>
using namespace std;
template <class _Ty1, class _Ty2>
class Fox
{
public:
	Fox(_Ty1 one, _Ty2 two) :one(one), two(two) {}
	friend ostream& operator<<(ostream& out, const Fox& fox)
	{
		out << fox.one << " " << fox.two;
		return out;
	}
protected:
	_Ty1 one;
	_Ty2 two;
};

template <class _Ty1, class _Ty2>
class Data
{
public:
	Data(_Ty1 one, _Ty2 two) :one(one), two(two) {}
	void print()
	{
		cout << one << " " << two << endl;
	}
protected:
	_Ty1 one;
	_Ty2 two;
};
template <class _Ty>
void print(_Ty data)
{
	cout << data << endl;
}
int main() 
{
	Data<Fox<string, int>, Fox<double, double>>
	mData2(Fox<string, int>("狐狸", 13), Fox<double, double>(100.0, 100.0));
	//上面一行顶下面4行
	Fox<string, int> fox1("狐狸",13);
	Fox<double, double>foxscore(100.0,100.0);
	Data<Fox<string, int>, Fox<double, double>> mData(fox1, foxscore);
	mData.print();
	//隐式调用
	print(Fox<string, int>("小狐狸", 15));
	//显式调用
	print<Fox<string, int>>(Fox<string, int>("小狐狸", 21));
	//起别名简化代码
	using FoxType= Fox<string, int>;
	print<FoxType>(FoxType("大狐狸", 3));


}

函数模板的重载

模板和普通函数,调用类型一致的情况下,优先调用普通函数

两个模板都成立,优先相似度高的模板

#include <iostream>
using namespace std;

void print(int a,string b) 
{
    cout << "普通函数" << endl;
}
template<class _Ty1,class _Ty2>
void print(_Ty1 a, _Ty2 b)
{
    cout << "两个类型" << endl;
}
template <class _Ty>
void print(_Ty a, _Ty b)
{
    cout << "一个类型" << endl;
}
int main() 
{
    print(15,string("dasdas"));//调用普通函数
    print<int, string>(12, "调用两个类型模板");//显示调用百分百调用模板
    print(12, string("调用两个类型模板"));

    print(12, 12); // 相似度高 调用一个类型
    return 0;



}

类模板特化

特化:局部特化 完全特化

#include<iostream>
#include<string>
using namespace std;
template<class _Ty1,class _Ty2 >
//普通类模板
//两个未知类型
class Fox
{
public:
    Fox(_Ty1 one, _Ty2 two) :one(one), two(two) {}
    void print() 
    {
        cout << one << "" << two << endl;
        cout << "原生模板" << endl;


    }
protected:
    _Ty1 one;
    _Ty2 two;

};
class Data
{
public:Data(int a, int b) :a(a), b(b) {};
      void printf()
      {
          cout << a << " " << b << endl;
  
      }

protected:
    int a;
    int b;

};
//特殊化 ,局部特化,一个未知参数
template<class _Ty >
class Fox<_Ty,_Ty>//产生特化类 类名要用:类型<类名>
{
public:
    Fox(_Ty one, _Ty two) :one(one), two(two) {}
    void print()
    {
        one.printf();
        two.printf();//针对特殊化数据做特殊化处理
        cout << "局部特化" << endl;
    }
protected:
    _Ty one;
    _Ty two;

};
//完全特化
template<>
class Fox<string, string>
{
public:
    Fox(string one, string two) :one(one), two(two) {};
    void print() 
    {
        cout << one << endl;
        cout << two << endl;
        cout << "完全特化" << endl;

    }
protected:
    string one;
    string two;
};

int main() 
{
    Fox<string,int> fox1("小狐狸",3);//原生模板
    fox1.print();
    Fox<string, string> fox2(string("大狐狸"), string("大大狐狸"));//完全特化
    fox2.print();
    Fox<Data, Data> dfox(Data(3, 4), Data(8, 9));//局部特化
    
    dfox.print();
}

针对不同的特化进行不同情况下模板的处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值