Effective C++ 3nd 读书摘要(七、模板与泛型编程)Item41 - 48

基于GIS的生态安全网络格局构建(附练习数据下载) 阅读详情

七、模板与泛型编程
C++ template mechanism is itself Turing-complete: it can be used to compute any computable value.

Item41. 了解隐式接口和编译期多态
对class而言,接口是显式的,以函数签名为中心;多态是通过virtual函数发生于运行期。


对template来讲,接口是隐式的,奠基于有效表达式,在编译期完成检查;多态通过templace具现化和函数重载解析发生于编译期。

 

Item42. 了解typename的双重意义
任何时候想要在template中指涉一个嵌套从属类型名称,就必须在紧临它的前一个位置放上关键字typename:(缺省状态下将不被认为是类型)

typename不可以出现在base classes list内的嵌套从属类型名称之前,也不可在member initialization list中作为base class修饰符,如:

 

Item43. 学习处理模板化基类内的名称
比如有两个公司

MsgSender向外发送信息。现在从MsgSender派生出一个类,可以志记:

这段代码将无法通过编译,因为不到具现化,LoggingMsgSender就无法知道MsgSender<Company>看起来像什么,确切地说是无法知道MsgSender<Company>是否有个可以供LoggingMsgSender调用的sendClear函数。这似乎与直觉违背,因为模板定义中确实有sendClear,但不要忘了模板是可以特化的:

 

假设有个CompanyZ坚持只有加密通讯:

因为CompanyZ没有sendCleartext函数,所以MsgSender template对它不适用,可以针对CompanyZ产生一个MsgSender特化版:(这里是全特化)

那么在上面出错的代码中,如果Company == CompanyZ,则就没有sendClear可以调用。

 

有两个比较好的办法可以纠正:

①

②

以上两种方法都是对编译器承诺“base class template的任何特化版本都将支持其一般(泛化)版本所提供的接口”。


不过编译器也不会乱搞,如果你打算这样:

LoggingMsgSender<CompanyZ> zMsgSender;
MsgInfo msgData;
...                                 // put info in msgData
zMsgSender.sendClearMsg(msgData);            // error! won't compile

Item44. 将与参数无关的代码抽离templates
例如:

这个template中的size_t就是与类型无关的。


一种改动方案可能是这样的:

这将允许derived classes改变矩阵大小,并决定内存分配方式。


可以在栈上分配:

也可以在堆上分配:

 

Item45. 运用成员函数模板接受所有兼容类型

即所谓member function templates。以上代码的含义是:对任何类型T和任何类型U,可以根据SmartPtr<U>生成一个SmartPtr<T>。

 

member function templates还可用于支持赋值操作:

注意以上唯有generalized copy constructor没有用户explicit。另外注意TR1::shared_ptrs和tr1::weak_ptrs在传输时,都有用const,而auto_ptr没有,因为在复制一个auto_ptr时,其实是被改动了。

 

在class内声明generalized copy constructor并不会阻止编译器生成它们自己的copy constructor,所以如果不想让编译器生成,你必须自己生成:

 

Item46. 需要类型转换时请为模板定义非成员函数(参见Item24)

这样可以通过混合运算:
Rational<int> oneHalf(1,2);
Rational<int> result = 2 * oneHalf;

因为当对象被声明为一个Rational<int>时,Rational<int>就被具现化出来,而作为过程的一部分,friend函数operator*也就被自动声明出来。后者是一个函数而非函数模板,因此编译器可在调用它时使用隐式转换函数(调用Rational的non-explicit构造函数),而这便是混合式调用之所以成功的原因。

 

在operator*中调用一个外部辅助函数可以将inline的冲击减到最小。

doMultiply作为一个template当然不支持混合式乘法,但它只被operator*调用,而后者支持了混合式操作,并将转换后的两个Rational对象传给适当的doMultiply template具现体。

 

Item47. 请使用traits classes表现类型信息
Traits是一种技术,它要求对内置类型和用户自定义类型的表现必须一样好。这种技术就是template加偏特化

。


考虑STL中的算法advance:
template<typename IterT, typename DistT>       // move iter d units
void advance(IterT& iter, DistT d);            // forward; if d < 0, move iter backward

现在有一组不同的iterator,希望advance针对不同的iterator采取不同的有效的处理手法:
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag: public input_iterator_tag {};
struct bidirectional_iterator_tag: public forward_iterator_tag {};
struct random_access_iterator_tag: public bidirectional_iterator_tag {};

我们希望有一种手法可以在编译器获取其信息。

 

现在定义一个模板struct来处理迭代器分类的相关信息:
template<typename IterT>          // template for information about
struct iterator_traits;            // iterator types

iterator_traits的动作方式是:针对每一个传入的IterT,都必须声明一个typedef为iterator_category,用来确认IterT的迭代器分类。


比如,对于deque的迭代器是可随机访问的,则:

而list的迭代器是可双向行进的,则:

至于iterator_traits的作用就是重复一下IterT是个什么:

以上是针对用户自定义类型的,对指针这种迭代器,因为它不能嵌套typedef,所以需要一个偏特化:

现在可以针对不同的iterator定义出一系列重载函数:

由于forward_iterator_tag继承自input_iterator_tag,所以上述doAdvance的input_iterator_tag版本也能够处理forward迭代器,这是public继承(is-a)的一个好处。

 

那么对advance,只要在其中调用doAdvance即可:

小结:一个traits class的用处为两点:
1. 建立一组重载函数或模板,彼此间的差异只在于各自的traits参数。
2. 建立一个控制函数或模板,它调用1中的函数并传递traits class所以提供的信息。

 

TR1引入了许多新的traits classes用以提供类型信息,有:is_fundamental<T>、is_array<T>、is_base_of<T1, T2> ......,共有50个以上。

 

Item48. 认识template元编程(TMP扫盲)
TMP:编写template-based C++程序并执行于编译期。

这样可以在编译期侦测出通常在运行期才能侦测到的错误;使用TMP的C++程序有较小的可执行文件、较短

的运行期、较少的内存需求。只是编译时间变长了。
(Item47的traits解法就是TMP——它是编译期发生于类型身上的if...else计算)


一个简单的例子:

 

TMP可以做以下三种事:
1. 确保度量单位正确。
2. 优化矩阵运算。
3. 可以生成客户定制之设计模式实现品。这项技术已经成为generative programming(殖生式编程)的一个基础。


TMP will probably never be mainstream, but for some programmers
 — especially library developers — it's almost certain to be a staple.

UE5热更新(通过Pak包加载关卡资源,并添加到流关卡) 请先阅读我上一篇文章)** 阅读详情

相关推荐

ORB-SLAM3的Euroc数据集测试

(一)测试运行 不同模式测试过程(以MH_03为例) 1、pure mono 运行SLAM: cd ORB-SLAM3/Example #run slam ./Monocular/mono_euroc ../Vocabulary/ORBvoc.txt ./Monocular/EuRoC.yaml "$pathDatasetEuroc"/MH03 ./Monocular/EuRoC_TimeStamps/MH03.txt dataset-MH03_mono 利用ORB-SLAM3自带..

ljtx200888的博客 9146

【经验】实现STL算法时遇到的模板编译错误问题

在实现set_union算法时调用了自己写的copy算法,出现了以下问题。 Error 1 error C2665: 'xyz_stl::__copy' : none of the 2 overloads could convert all the argument types 即“__copy的2个重载不能转换所有的参数类型”。 注:__copy是照着STL源码剖析进行命名的(实际上我倒...

weixin_30378623的博客 607

合成孔径雷达(SAR)的常见工作模式

随着星载SAR技术研究的深入发展,单一的条带模式已经无法满足当今时代的需求,因此许多新的工作模式相继被提出。这些新模式在分辨率和测绘宽度等方面都有所提高,接下来将简要介绍几种常用的工作模式。

m0_51390495的博客 2317

C++类模板详解

有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,如下面语句声明了一个类: class Compare_int{public : Compare(int a,int b) { x=a; y=b; } int max( ) { return (x>y)?x:y; } int min( ) { return (x

sfe1012 Na~喊 -- 心系一处 睥睨群雄 Blog 2548

ArcMap投影变换避坑指南:为什么你的坐标转换总出错?常见问题解析与解决方案

本文深入解析ArcMap中坐标转换与投影变换的核心区别与常见陷阱。针对坐标转换总出错的问题,从混淆“定义投影”与“投影变换”、栅格数据重采样选择、矢量数据地理变换参数设置等关键环节,提供清晰的避坑指南与实战解决方案,帮助用户确保空间数据的精确匹配。

weixin_29210727的博客 357

超详细!新手必看STM32-DMA配置与实验(串口使用DMA发送数据)

DMA就是:直接存储器访问。DMA传输数据从一个地址空间复制到另一个地址空间,提供在外设和存储器或者存储器和存储器之间的高速数据传输。

qq_1033275663的博客 2万+

Effective C++ 3nd 读书摘要(Third Edition 55 Specific Ways to Improve Your Programs and Design)

一、让自己习惯C++ Item1. 视C++为一个语言联邦 C++由以下部分组成:C、Object-Oriented C++、Template C++、STL Item2. 尽量以const、enum、inline代替#define Item3. 尽可能使用const 1.一共有这样几种const用法:char greeting[] = "Hello";

thy专栏 1302

Python爬虫实战:5分钟搞定大众点评评论数据抓取(附完整代码)

本文详细介绍了使用Python爬虫高效获取大众点评评论数据的5个关键技巧,包括环境配置、智能页面解析、反反爬策略、数据存储与容错设计以及性能优化。通过实战案例和完整代码,帮助开发者快速掌握文本挖掘技术,适用于市场分析和商业决策。

weixin_30660027的博客 290

Effective C++ 3nd 读书摘要(一、让自己习惯C++ ; 二、构造,析构,赋值运算)Item1 - 12

一、让自己习惯C++Item1. 视C++为一个语言联邦C++由以下部分组成:C、Object-Oriented C++、Template C++、STL Item2. 尽量以const、enum、inline代替#define Item3. 尽可能使用const1.一共有这样几种const用法:char greeting[] = "Hello";char *p = greetin

thy专栏 916

全球APN信息汇总

全球APN信息,电信APN,移动APN,联通APN,台湾APN,马来西亚APN,俄罗斯APN,日本APN,泰国APN,美国APN,英国APN,法国APN,德国APN,意大利APN,葡萄牙APN,土耳其APN,荷兰APN,丹麦APN,比利时APN,爱尔兰APN,新加坡APN,越南APN,老挝APN,菲律宾APN,印尼APN,泰国APN,柬埔寨APN,巴基斯坦APN,印度APN,奥地利APN,保加利亚APN,捷克APN,立陶宛APN,罗马尼亚APN,挪威APN,希腊APN,匈牙利APN,瑞士APN,乌克兰APN

renkai721的专栏 2796

PCL 计算点云AABB包围盒的体积【2026最新版】

AABB包围盒又称了 轴对齐包围盒,是点云包围盒里最简单的一种,其计算方法也极其简单。获取包围盒之后,根据包围盒的长宽高进行体积计算即可!博客长期更新,本文最近一次更新时间为:2026年5月3日。

点云侠的博客 2295

Effective C++ 3nd 读书摘要(三、资源管理 ;四、设计与声明;五、实现)Item13 - 31

三、资源管理Item13. 以对象管理资源在构造函数中获得资源并在析构函数中释放资源。如tr1::shared_ptr Item14. 在资源管理类中小心copying行为抑制copying、施行引用计数法 Item15. 在资源管理类中提供对原始资源的访问一如Item18的忠告,通常显式转换函数如get()、string::c_str()是比较受欢迎的,因为不太可能被误用。 

thy专栏 891

多智能体系统在AI物流优化中的实际应用案例

订单波峰波谷难应对(如双11订单量暴增300%);动态干扰难处理(如突发交通拥堵、客户临时改地址);全局优化难实现(单辆车最优≠整体最优)。本文聚焦“多智能体系统(MAS)”这一AI技术,讲解其如何通过“群体智能”破解物流调度难题,并结合实际案例展示落地效果。本文从“生活故事→核心概念→技术原理→实战案例→未来趋势”逐步展开,用“快递员团队协作送外卖”类比MAS运作,结合Python代码模拟任务分配,最后通过某物流企业的真实项目验证效果。

AIGC应用创新大全的博客 1632

Effective C++ 3nd 读书摘要(八、定制new和delete)Item49 - 52

八、定制new和deleteItem49. 了解new-handler的行为当然operator new抛出异常以反映内存需求出错之前,会先调用一个客户指定的错误处理函数(new-handler)。namespace std {  typedef void (*new_handler)();  new_handler set_new_handler(new_handler p) throw();}

thy专栏 890

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Effective C++ 3nd 读书摘要(六、继承与面向对象设计)Item32 - 40

六、继承与面向对象设计Item32. 确定你的public继承塑模出is-a关系(即Liskov Substitution Principle)下面是一个不严谨的public继承:class Bird {public: virtual void fly(); // birds can fly ...};class Penguin:p

thy专栏 867

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Effective C++ 3nd 读书摘要(九、杂项讨论)Item53 - 55

九、杂项讨论Item53. 不要轻忽编译器的警告比如:class B {public: virtual void f() const;};class D: public B {public: virtual void f();}; 编译器会警告:warning: D::f() hides virtual B::f()因为D中的f()没有const。 

thy专栏 794

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 254

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 349

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 394

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 88

【C++——类和对象(上)】筑基篇:以封装奠定面向对象之基

本文系统梳理C++类与对象的核心知识点,涵盖类的定义、访问限定符(public/private)、类作用域、对象实例化及内存布局。重点解析封装思想、this指针机制、空类大小为1字节的原因,以及类与对象在内存中的存储差异。通过对比C语言结构体与C++类,揭示面向对象设计的优势:数据保护、接口统一、命名隔离与代码可维护性提升。内容由浅入深,适合作为学习笔记与复习参考。

2602_95684935的博客 492

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 307

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 450

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 251

1-10 PostgreSQL中多表连接全解:inner/left/right/full/cross join

本文基于 PostgreSQL 15+ 完整拆解 5 种主流连接:内连接、左连接、右连接、全连接、笛卡尔连接。结合可落地的测试数据,演示每种连接的执行逻辑、返回结果,重点剖析 NULL 值对 JOIN 匹配的核心影响,彻底解决多表连接数据丢失、匹配异常、结果错乱的问题。

zhangjw34的专栏 105

【C++ 基础入门】C++继承(下):问题、底层原理与组合

C++继承(菱形继承的问题、虚继承原理、继承与组合、构造顺序)

2601_96587588的博客 802
上一篇: Effective C++ 3nd 读书摘要(六、继承与面向对象设计)Item32 - 40
下一篇: Effective C++ 3nd 读书摘要(八、定制new和delete)Item49 - 52
thy38
博客等级 码龄19年 184粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值