16.5模板特例化

//第一个版本,可以比较任意两个类型
template<typename T>
int compare(const T&p1, const T&p2)
{cout << "太过泛型的compare版本"<<endl;return strcmp(p1, p2);
}//第二个版本处理字符串字面量
template<size_t N,size_t M>
int compare(const char(&p1)[N], const char(&p2)[M])
{cout << "特例化的版本,能够接受字符串指针的compare" << endl;return strcmp(p1,p2);
}
void test01()
{const char* p1 = "h1", * p2 = "MOM";compare(p1, p2); //调用第一个模板compare("hi", "mom");//调用有两个非类型参数的版本}

无法将一个指针转换为一个数组的引用,但是数组可以转换为指针,所以第二个版本是无法实例化的

定义函数模板特例化

template<>
//对比下template<typename T>int compare(const T& p1, const T& p2)的版本
//这个特例化的函数要求一个指向此类型const版本的引用
//一个指向const char 的const指针的引用
//怎么做的结果实际上就是直接帮编译器接手下面编译器本来要生成的版本
int compare(const char* const&p1, const char* const& p2)
{//const char*是针对字符串指针的,而const是针对第一个版本的constcout << "调用特例化的compare" << endl;return strcmp(p1, p2);
}

函数重载与模板特例化
compare(“hi”,“mom”)
由于是特例化版本,并不行独立的非函数模板,还是调用数组引用的版本,如果是函数,就遵行函数匹配规则

类模板·特例化
这个特例化的类模板是用来将Sales_data对象保存在无序容器中

template<class T>class std::hash;
struct Sales_data
{  friend class std::hash<Sales_data>;Sales_data() = default;Sales_data(const string &s):bookNO(s){ }Sales_data(const string &s,unsigned n,double p):bookNO(s),units_sold(n),revene(p){}Sales_data(istream& is){read(is, *this);}string isbn()const { return this->bookNO; }Sales_data& combine(const Sales_data&rhs){units_sold += rhs.units_sold;revene += rhs.revene;return *this;}double avg_price()const{if (units_sold){return revene / units_sold;}else{return 0;}}istream& read(istream& is, Sales_data& item){double price = 0;is >> item.bookNO >> item.units_sold >> price;item.revene = price * item.units_sold;return is;}string bookNO;unsigned units_sold = 0;double revene = 0.0;};Sales_data add(const Sales_data& lhs, const Sales_data& rhs)
{Sales_data sum = lhs;sum.combine(rhs); return sum;
}ostream& print(ostream& os, const Sales_data& item)
{os << item.isbn() << " " << item.units_sold << " "<< item.revene << " " << item.avg_price();return os;
}bool operator== (const Sales_data& lhs, const Sales_data& rhs)
{return lhs.isbn() == rhs.isbn() && lhs.units_sold == rhs.units_sold &&lhs.revene == rhs.revene;
}//这下面的代码才是重点,上面只是补充Sales_data类的完整namespace std
{template<>struct hash<Sales_data> //特例化版本 模板参数为sales_data{//用来散列一个无需容器的类型必须要定义下列类型typedef size_t result_type;typedef Sales_data argument_type; //此类型需要==size_t operator()(const Sales_data& s)const;//类使用合成的拷贝控制成员和默认构造函数};size_t hash<Sales_data>::operator()(const Sales_data& s)const{return hash<string>()(s.bookNO) ^hash<unsigned>()(s.units_sold) ^hash<double>()(s.revene);}
}//关闭std命名空间; 右花括号是没有分号的int main()
{unordered_multiset<Sales_data>Sdest;}

类模板部分特例化

//原始的。最通用 或最泛的版本
template<class T>struct Remove_reference
{typedef T type;
};//部分特例化版本,将用于左值引用和右值引用
template<class T>struct Remove_reference<T&>//左值引用
{typedef T type;
};template<class T>
struct Remove_reference<T&&>//右值引用
{typedef T type;
};void test01()
{int i = 0;//使用原始模板Remove_reference<decltype(42)>::type a;//使用T&的特例化版本Remove_reference<decltype(i)>::type b;//使用T&&的特例化版本Remove_reference<decltype(std::move(i))>::type c;}

特例化成员而不是类

template<typename T>struct Foo
{Foo(const T &t =T()):mem(t){ }void Bar(){ cout << "使用泛的Bar()" << endl;}T mem;
};template<> //特例化Foo模板类的成员Bar
void Foo<int>::Bar()
{cout << "使用特例化版本的Foo<int>::Bar()" << endl;
}void test02()
{Foo<string>fs;fs.Bar();Foo<int>fi;fi.Bar();
}

练习16.62

    unordered_multiset<Sales_data>Sdest;// test02();Sales_data b("abc",1,2);Sales_data c("vvx",2,19);Sdest.insert(b);Sdest.insert(c);cout << Sdest.size() << endl;for (auto sd : Sdest){print(cout, sd) << endl;}

练习16.63 64

template<typename T>
int vec(vector<T>& vec, const T& v)
{int ret = 0;for (auto X : vec){if (X == v){++ret;}}return ret;}template<>
int vec(vector<const char *>& vec,const  char *const & v)
{int ret = 0;for (auto X : vec){if (!strcmp(X, v))++ret;}return ret;
}void test03()
{vector<double>a = { 1.1,2.2,3.3,4.4,5.5 };vector<int>b = { 1,1,1,3,4,5 };vector<string>c = { "1","1","2","2" };vector<const char*>d = {"123","sdas","ss"};const char* p1 = "123";const char* p2 = "sdas";const char* p3 = "ss";cout << vec(a, 1.1) << endl;cout << vec(b, 1) << endl;cout<<vec(c,string("2"))<<endl;cout<<vec(d,p1)<<endl;
}

练习16.65

template<>
string debug_rep(char* p)
{return debug_rep(string(p));
}
template<>
string debug_rep(const char* cp)
{return debug_rep(string(cp));
}

练习16.66
不希望使用通用模板版本,就自己定义类或函数的特例化版本
重载,函数匹配过程中会在重载函数中选择最佳匹配,小心设计

练习16.67
不会,特例化不会影响函数匹配,匹配规则是函数优先,
特例化版本只是接管了本来编译器应该生成版本实例化的工作
当某个模板是最佳匹配还是特殊化版本,直接略过原模板,直接使用这个模板

c++primer第十六章模板特例化相关推荐

  1. C++ Primer 第十六章 模板与范型编程

    16.1 模板定义     模板和c#范型一样,建立一个通用的类或函数,其参数类型和返回类型不具体指定,用一个虚拟的类型来代表,通过模板化函数或类实现代码在的重用.     定义语法是:    tem ...

  2. C++ Primer plus学习笔记-第十六章:string类和标准模板库

    第十六章:string类和标准模板库 前言:这一章已经相当靠近全书的后面部分了:这一章我们会深入探讨一些技术上的细节,比如string的具体构造函数,比如适用于string类的几个函数,比如我们还会介 ...

  3. C++ Primer学习笔记-----第十六章:模板与泛型编程

    模板是C++中泛型编程的基础. 模板是蓝图,用来创建类型,创建的类型就是模板的实例,就好像我们用一个类型创建相应的实例一样. 函数模板 template<typename T> //模板参 ...

  4. C++ Primer Plus(第六版)第十六章课后习题

    C++ Primer Plus(第六版)第十六章课后习题 16.10.1 #include <iostream> #include <string> using namespa ...

  5. C++程序设计原理与实践 习题答案 第二十六章 第26章习题答案

    第二十六章:测试 习题答案 本章的BinarySearch Binary_Search.h 26.2 26.2 测试集 26.3 26.4 26.5 26.8 and 26.9 26.8 测试集 26 ...

  6. 《深入理解 Spring Cloud 与微服务构建》第十六章 Spring Boot Security 详解

    <深入理解 Spring Cloud 与微服务构建>第十六章 Spring Boot Security 详解 文章目录 <深入理解 Spring Cloud 与微服务构建>第十 ...

  7. Web Hacking 101 中文版 十六、模板注入

    十六.模板注入 作者:Peter Yaworski 译者:飞龙 协议:CC BY-NC-SA 4.0 模板引擎是允许开发者或设计师在创建动态网页的时候,从数据展示中分离编程逻辑的工具.换句话说,除了拥 ...

  8. 【正点原子FPGA连载】第十六章Petalinux设计流程实战摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Linux开发指南

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: h ...

  9. 【Linux命令】《鸟哥Linux基础》第十六章 进程管理与SELinux初探

    第十六章 进程管理与SELinux初探 16.1 什么是进程(process) Linux下的所有命令与你能够执行的操作 ===>都与权限有关 如何判断权限? 账号管理中的UID.GID:文件属 ...

最新文章

  1. 东莞市初中生中考计算机内容,2019年广东东莞市中考考试科目及内容
  2. 谈谈 Android 中的 PathClassLoader 和 DexClassLoader
  3. 1.7Oob 继承关系中构造方法的使用
  4. 再度吐槽,PHP在centos7的安装方式稍不注意可能就打击你的积极性
  5. 阿里云直播转点播最佳实践
  6. MyBatis Plus 批量数据插入功能,yyds!
  7. Java操作Excel中HSSFCell.CELL_TYPE_STRING、BOOLEAN、NUMERIC无定义解决方法
  8. 整理下Jquery中用到的英语单词 带音标
  9. 修复pdf字体嵌入问题
  10. 拾方易公众号运营成本低么?
  11. 陈庆平获评2021年湖南省“最美科技工作者”
  12. 【论文】 Skeletonization of Ribbon-Like Shapes Based on Regularity and Singularity Analyses
  13. 在线加密解密网站大全2022(更新中ing)
  14. 云南新开普智慧校园一卡通解决方案,K12智慧校园信息化建设解决方案
  15. 实验三 基本表的定义、删除与修改
  16. 阿里云dos木马及xmrig矿毒
  17. sudo: gedit:找不到命令
  18. 互联网巨头放贷的AB面
  19. 从风光到巨额亏损 老企业夏普衰落真相是什么?
  20. 数字地图将成正果【转载】

热门文章

  1. git --allow-unrelated-histories
  2. root账号无法通过SSH登录阿里云ECS
  3. 计算机基础与应用答案,第4章 课后作业【含答案】 计算机基础与应用
  4. MSDN系列 14 -- NDIS Protocol Driver 入门
  5. TMS320C6678开发笔记---IBL编译与分析3
  6. 图片如何转换为文字?这些软件可以实现
  7. java word 分页显示_jsp转word + 分页
  8. C语言中arr[0] 、arr 、arr
  9. 计算机xp上网运行很慢,如何解决WinXP打开我的电脑很慢的问题?
  10. 3.2 写一个UR机器人运动学库