模板参数分类类型形参与非类型形参。
//非类型参数+非类型模板参数
template
//float double string不能做非类型模板参数
//int short char long long long可以 整形
class Array
{
public://Array()//{// N = 10;//无法修改 N是常量 修改会报错//}
private:T _a[N];
};
int main()
{Array a1; //100Array a2; //1000return 0;
}
通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得
到一些错误的结果。此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊
类型所进行特殊化的实现方式。模板特化中分为函数模板特化与类模板特化。
//模板的特化
template
bool IsEqual(T& left, T& right)
{return left == right;
}//特化 (针对某些类型的特殊化处理) 加在函数名后面
template<>
bool IsEqual(char*& left, char*& right)
{return strcmp(left, right) == 0;
}
//接下来对这个类进行特化
template
class Data
{
public:Data() { cout << "Data" << endl; }
private:T1 _d1;T2 _d2;
};//特化 加在类名后面
//全特化 全部的参数都特化
template<>
class Data
{
public:Data() { cout << "全特化:Data" << endl; }
private:
};
//偏特化/半特化
//第一种
template
class Data
{
public:Data() { cout << "偏特化:Data" << endl; }
private:
};
//第二种
template
class Data
{
public:Data() { cout << "偏特化:Data" << endl; }
private:
};
//第三种
template
class Data
{
public:Data() { cout << "偏特化:Data" << endl; }
private:
};
int main()
{int a = 0, b = 1;cout << IsEqual(a, b) << endl;const char* p1 = "hello";const char* p2 = "world";cout << IsEqual(p1, p2) << endl;Data d1;//偏特化Data d2;//调全特化版本Data d3;//调偏特化版本Data d4;//普通版本//第一个是int就调半特化 如果第二个是char那就是全特化//第一个不是int 就调普通版本Data d5;Data d6;Data d7;//可调指针 引用return 0;
}
Func.h Func.cpp Test.cpp
1.预处理 展开头文件/宏替换/条件编译/去掉注释
Func.i Test.i
2.编译 检查语法 生成汇编代码
Func.s Test.s
3.汇编 将汇编代码转成二进制的机器码
Func.o Test.o
4.链接 将目标文件合到一起 编译时F1和F2函数由声明 所以编译过来 链接时要去Func.o中找F1和F2的地址
a.out 这里F1找到了 F2没找到 所以报了一个链接错误
分离编译
项目工程中一般将函数或者类的声明放到.h
将函数或者类的定义放到.cpp
为什么要分离编译呢? 方便查看和维护
最后链接错误 普通函数和类可以找到地址 而模板函数/类模板找不到
解决方法:
1.将声明和定义放到一个文件 "xxx.hpp" 里面或者xxx.h其实也是可以的。推荐使用这种。
2.模板定义的位置显式实例化。
最好使用1 都放到.h中就可以了
#include "Func.h"int main()
{F1(); //可以调到 call 一个函数地址F2(10); //模板的话 出了问题 链接错误//函数模板找不到相关地址 符号表里面没有F2()//显示实例化后可以找到F2(10.11);//突然来个double 又找不到了 用一个就要实例化一个F2('a');return 0;
}
#pragma once
#include
using namespace std;void F1();template
void F2(const T& x)
{cout << "void F2(const T& x)" << endl;
}
#include "Func.h"void F1()
{cout << "F1()" << endl;
}//template
//void F2(const T& x)
//{
// cout << "void F2(const T& x)" << endl;
//}解决模板不能分离
1.显示实例化 不常用 因为不方便
2.粗暴 就是不要分离编译了
//template
//void F2(const int& x);
//
//template
//void F2(const double& x);
//直接放到.h里
//所以模板放.h
//函数都可以
优点:
缺点:
下一篇: 美术学习总结