
本文共 4481 字,大约阅读时间需要 14 分钟。
【C/C++基础进阶系列】C/C++ 泛型 -- 函数模板
【C/C++基础进阶系列】C/C++ 泛型 -- 函数模板
【1】函数模板 -- 基础与实例化
#include
// 基本范例// a) 模板的定义是以template关键字开头// b) 类型模板参数T前面用typename来修饰,因此遇到typename就该知道其后面跟的是一个类型// c) 类型模板参数T(代表是一个类型)包括前面的修饰符typename/class都用<>括起来// d) T这个名字可以换成任意其他标识符,对程序没有影响,用T只是一种编程习惯
namespace _nmsp1 {// template
// 实例化// 实例化,编译时,用具体的“类型”代替“类型模板参数”的过程就叫做实例化(也称为代码生成器)// .obj文件在编译完成后就会产生// .obj文件的格式一般会被认为是一种COFF——通用对象文件格式(Common Object File Format);
int main() {// int Sub
(3, 5)// double Sub// 在编译阶段,编译器需要能够找到函数模板的函数体部分// string a("abc"), b("def");// string addresult = Sub(a, b); // 编译器报错,string类型相减不合法// 合法性的判断在编译阶段判定
}
【2】函数模板 -- 模板参数的推断
#include
namespace _nmsp1 {template <typename v, typename t, typename u>V Add(T tv1, U tv2) {return tv1 + tv2;}
// 模板参数的推断// 常规的参数推断// 通过<>可以只指定一部分模板参数的类型,另外一部分模板参数的类型可以通过调用时给的实参来推断;int main() { // cout << Add<..., ..., double>(15, 17.8) << endl; // 错误,针对情况(1)指定返回值类型,无法跳过前两个类型 // cout << Add(15, 17.8) << endl; // 正确,针对情况(1)指定返回值类型 // cout << Add (15, 17.8) << endl; // 针对情况(2),V是第一个参数,从而不需要明确指定T、U的类型 // T、U的类型由实参自动推断得出}
}
【3】函数模板 -- 重载
#include
#pragma warning(disable : 4996)namespace _nmsp1 {template
// 函数模板重载int main() {_nmsp1::myfunc(12); // 调用 void myfunc(int tmpvalue)char* p = nullptr; _nmsp1::myfunc(p); // 调用 void myfunc(T* tmpvalue)_nmsp1::myfunc(12.1); // 调用 void myfunc(T tmpvalue)}
【4】函数模板 -- 特化
#include
#pragma warning(disable : 4996)namespace _nmsp2 {// 泛化版本template <typename t, typename u>void tfunc(t& tmprv, u& tmprv2) {cout << "tfunc泛化版本" << endl;cout << tmprv << endl;cout << tmprv2 << endl;}
// 全特化版本template < typename t = int, typename u = double> void tfunc(int& tmprv, double& tmprv2) { cout << "---------------begin------------" << endl; cout << "tfunc特化版本" << endl; cout << tmprv << endl; cout << tmprv2 << endl; cout << "---------------end------------" << endl; }// 重载函数void tfunc(int& tmprv, double& tmprv2) { cout << "---------------begin------------" << endl; cout << "tfunc普通函数" << endl; cout << "---------------end------------" << endl;}// 模板参数数量上的偏特化// 模板参数范围上的偏特化
}
int main() {const char* p = "I Love China!"; int i = 12; _nmsp2::tfunc(p, i); // 调用泛化版本int k = 12; double db = 15.8; _nmsp2::tfunc(k, db); // 调用普通函数const int k2 = 12; _nmsp2::tfunc(k2, db); // 调用偏特化版本double j = 18.5; _nmsp2::tfunc(j, i); // 调用偏特化版本}
【5】函数模板 -- 缺省参数
#include
- #include
#pragma warning(disable : 4996)namespace _nmsp1 {int mf(int tmp1, int tmp2) { return 1; }int mf2(int tmp1, int tmp2) { return 10; }
typedef int(*FunType)(int, int);templatevoid testfunc(t i, t j, f funcpoint = mf) { cout << funcpoint(i, j) << endl; }template void testfunc2(t m) { t tmpvalue = m; cout << tmpvalue << endl; }
}
int main() {_nmsp1::testfunc(15, 16); // 调用 testfunc(T i, T j, F funcpoint = mf)_nmsp1::testfunc(15, 16, _nmsp1::mf2); // 调用 testfunc(T i, T j, F funcpoint = mf2)_nmsp1::testfunc2(12); // 调用 testfunc2(U m)}
【6】函数模板 -- 非类型模板参数
#include
- #include
#pragma warning(disable : 4996)namespace _nmsp2 {template <typename t, typename u, int val = 100>auto Add(t tv1, u tv2) {return tv1 + tv2 + val;}
templatevoid mft() { cout << "mft()执行了" << endl; }double g_d = 1.3;template auto Add2() { return 100; }
}
int main() {_nmsp2::Add<float, float>(22.3f, 11.8f); // val取100_nmsp2::Add<float, float, 800>(22.3f, 11.8f); // val取800// int k = 1000; // cout << _nmsp2::Add<float, float, k>(22.3f, 11.8f) << endl; // 编译出错,k在编译时没有确定具体的值
_nmsp2::mft; // 调用_nmsp2::Add2 (); // 调用
}
参考致谢本博客为博主学习笔记,同时参考了网上众博主的博文以及相关专业书籍,在此表示感谢,本文若存在不足之处,请批评指正。本文若存在不足之处,请批评指正。
【1】C++ 新经典【2】C++11/14 高级编程 Boost 程序库探秘
发表评论
最新留言
关于作者
