Effective C++ 条款45:运用成员函数模板接受所有兼容类型

Effective C++ 条款45:运用成员函数模板接受所有兼容类型


核心思想使用成员函数模板(member function templates)生成可接受兼容类型的函数,特别是泛型拷贝构造函数和赋值操作符,同时避免抑制编译器生成的默认特殊成员函数。

⚠️ 1. 智能指针的类型转换问题

问题根源

  • 希望智能指针能模拟内置指针的隐式转换(如派生类指针到基类指针)
  • 模板实例化后不同模板参数生成的是不同类,无法直接转换
  • 需要为每种可能的兼容类型单独编写构造函数,不现实

错误示例

template<typename T>
class SmartPtr {
public:explicit SmartPtr(T* realPtr); // 原始指针构造函数// 希望支持以下转换,但无法实现:// SmartPtr<Base> = SmartPtr<Derived>// SmartPtr<const T> = SmartPtr<T>
};

🚨 2. 成员函数模板解决方案

解决方案

  • 声明成员函数模板(泛型拷贝构造函数)
  • 使用类型约束确保安全转换

优化实现

template<typename T>
class SmartPtr {
public:template<typename U>SmartPtr(const SmartPtr<U>& other)  // 泛型拷贝构造: heldPtr(other.get()) { }     // 使用get()获取原始指针T* get() const { return heldPtr; } // 获取原始指针private:T* heldPtr; // 持有原始指针
};

类型安全约束

  • 添加编译期类型检查,确保U可隐式转换为T
template<typename T>
class SmartPtr {
public:template<typename U, typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>SmartPtr(const SmartPtr<U>& other): heldPtr(other.get()) { }// ...
};

⚖️ 3. 赋值操作与兼容性处理

问题场景

  • 需要支持不同类型的智能指针赋值
  • 同时要避免编译器自动生成默认拷贝操作

解决方案

  • 为赋值操作定义成员模板函数
  • 显式声明普通拷贝操作以避免被模板隐藏

完整实现

template<typename T>
class SmartPtr {
public:// 泛型拷贝构造template<typename U, typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>SmartPtr(const SmartPtr<U>& other);// 显式声明普通拷贝构造和赋值(防止被模板隐藏)SmartPtr(const SmartPtr&); SmartPtr& operator=(const SmartPtr&);// 泛型赋值操作符template<typename U, typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>SmartPtr& operator=(const SmartPtr<U>& other);// ... 其他成员 ...
};

注意事项

  • 成员函数模板不改变语言规则:拷贝构造函数不会阻止编译器生成默认拷贝构造函数
  • 若需要完全控制,可显式定义或使用=default/=delete

💡 关键设计原则

  1. 使用成员函数模板实现泛型构造
    成员函数模板可生成接受任意兼容类型的构造函数和赋值函数

    template<typename T>
    class SharedPtr {
    public:template<typename Y>explicit SharedPtr(Y* p);  // 从任意类型指针构造template<typename Y>SharedPtr(const SharedPtr<Y>& r); // 兼容类型拷贝构造
    };
    
  2. 添加类型转换约束
    使用std::enable_if和类型特征确保安全转换

    template<typename T>
    class SmartPtr {template<typename U, typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>SmartPtr(const SmartPtr<U>&);
    };
    
  3. 显式声明默认函数
    避免成员模板隐藏编译器生成的默认函数

    template<typename T>
    class SmartPtr {
    public:// 显式声明拷贝操作SmartPtr(const SmartPtr&); SmartPtr& operator=(const SmartPtr&);// 成员模板构造函数...
    };
    

实战:跨类型智能指针赋值

class Base { /*...*/ };
class Derived : public Base { /*...*/ };SmartPtr<Base> pBase(new Base);
SmartPtr<Derived> pDerived(new Derived);// 使用成员模板实现兼容类型赋值
pBase = pDerived;  // 正确:通过泛型赋值操作符// 错误示例:类型不兼容
SmartPtr<int> pInt(new int);
// pBase = pInt; // 编译错误:类型约束阻止转换

类型特征约束进阶

// 使用更精确的约束:派生关系
template<typename T>
class SmartPtr {template<typename U, typename = std::enable_if_t<std::is_base_of_v<T, U> || std::is_convertible_v<U*, T*>>>SmartPtr(const SmartPtr<U>&);
};

总结成员函数模板允许类模板生成接受任意兼容类型的函数,是实现泛型拷贝构造和赋值操作的关键技术。通过添加编译期类型约束(如std::enable_if和类型特征)确保转换安全,同时显式声明默认拷贝操作以避免被模板隐藏。这一技术广泛用于智能指针、迭代器等需要类型灵活性的场景,是编写高级模板代码的必备技能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919088.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华测科技(北京)的3D GPR数据分析

很高兴得到了张总的支持&#xff0c;获得了他们雷达的数据&#xff0c;并写了雷达数据读取和转换文件。1 背景搜索后发现 华测科技&#xff08;北京&#xff09;有限公司 的实力很强&#xff0c;因为他们的检测可达100km/h的时速。以前我只知道行业内 青岛中电众益 的3D GPR产…

X86、ARM与C86架构全面对比分析:性能、功耗、成本与生态系统

目录标题X86、ARM与C86架构全面对比分析&#xff1a;性能、功耗、成本与生态系统一、架构概述与发展背景1.1 X86架构&#xff1a;PC与服务器市场的传统霸主1.2 ARM架构&#xff1a;移动领域的王者与新兴服务器力量1.3 C86架构&#xff1a;国产x86兼容的创新尝试二、性能表现对比…

w嵌入式分享合集66

自己的原文哦~ https://blog.51cto.com/whaosoft/14132240 一、STM32的NRST管脚异常复位问题 这个问题是客户对开发的平台做EMS 浪涌测试的时候发生的&#xff0c;平台上使用了一个STM32G474 RCT6 MCU 。在某个等级的EMS 测试中&#xff0c; 客户发现MCU有时候会异常…

ZKmall开源商城的数据校验之道:用规范守护业务基石

在电商系统里&#xff0c;数据就像流淌的血液 —— 用户填的手机号、下单的商品数量、支付的金额&#xff0c;每一个数字、每一段文字都得靠谱。要是数据出了错&#xff0c;轻则订单下不了&#xff0c;重则钱货两空。ZKmall 开源商城作为一个分布式电商系统&#xff0c;每天要处…

QML实现数据可视化

界面样式 项目开发流程 1.通过QtCreator创建一个Qt Quick插件,插件命名为CarPanMod; 2.通过QtCreator创建一个Qt Quick Application,命名为QmlPro; 3.在插件CarPanMod中实现条形图,折线图和饼状图的绘制; 4.在应用程序QmlPro中,添加插件的导入路径; 5.在应用程序中,通过i…

实时计算 记录

《大数据架构师》海量实时广告流平台架构设计与实践 《架构师必备技能之集群资源评估.pdf》 参考&#xff1a; 大型广告系统架构与实现 架构图

gitee_流水线搭配 Dockerfile 部署vue项目

使用 gitee流水线搭配docker,编写Dockerfile文件进行自动部署Vue项目 gitee流水线 基本配置跟另外一篇文章中类似 gitee_配置自动部署vue项目-CSDN博客 需要修改的只是脚本执行 # 构建阶段脚本echo 清理旧文件 rm -rf dist echo 配置 Git 参数 git config --global http.pos…

Win10快速安装.NET3.5

按Windows键输入CONTROL打开“控制面板”点击“程序”点击“启用或关闭Windows功能”勾选“.NET Framework3.5&#xff08;包括.NET2.0和3.0&#xff09;”点击确定随后选择从更新下载&#xff08;具体提示忘记了&#xff09;&#xff0c;之后windows会自动安装

Docker Compose 入门教程

一、Docker Compose 简介 Docker Compose 是 Docker 官方提供的多容器编排工具&#xff0c;通过 YAML 文件&#xff08;docker-compose.yml&#xff09;定义应用程序的服务、网络和卷&#xff0c;实现一键式容器管理。其核心优势包括&#xff1a; 简化多容器管理&#xff1a;通…

Tomcat架构深度解析:从Server到Servlet的全流程揭秘

第一章&#xff1a;Tomcat架构概述1.1 Tomcat的角色与定位&#xff1a;Web服务器 vs Servlet容器Tomcat 是什么&#xff1f;它既是一种轻量级 Web 服务器&#xff0c;也是一种符合 Java EE 规范的 Servlet 容器。Web服务器&#xff1a;类似 Nginx、Apache HTTP Server&#xff…

【Java web】HTTP 协议详解

一、什么是 HTTP&#xff1f;—— 互联网的 "快递员"你有没有想过&#xff0c;当你在浏览器输入www.baidu.com并按下回车时&#xff0c;背后发生了什么&#xff1f;为什么几秒钟后就能看到百度首页&#xff1f;这一切的背后&#xff0c;都离不开一个叫HTTP的 "快…

流式数据服务端怎么传给前端,前端怎么接收?

01 引言 大模型时代&#xff0c;尤其会话模型为了提高用户的使用体验&#xff0c;它不会将所有的数据加载完成一次响应给客户端&#xff0c;而是通过数据流&#xff0c;一点点的将数据慢慢呈现出来。 正是这种有趣的交互方式一次次将SSE&#xff08;Server Sent Event&#x…

ML307C 4G通信板:工业级DTU固件,多协议支持,智能配置管理

产品概述 ML307C 4G通信板是一款基于中移物联网ML307C模组的工业级DTU&#xff08;数据传输单元&#xff09;产品&#xff0c;专为工业物联网应用设计。我们的固件支持多种工业协议&#xff0c;具备远程配置、FOTA升级、数据加密等企业级功能&#xff0c;为您的工业设备提供稳定…

Sublime配置verilog开发环境-具备语法高亮、代码补全、自定义代码段及语法检查等功能,提升FPGA开发效率!

对于在学习FPGA开发之前使用过其他集成开发工具如VS、pycharm、keil或编辑工具如Sublime、VScode、Notepad的朋友&#xff0c;在使用Vivado时可能会像博主一样感觉自带编辑器用起来不太舒服&#xff0c;比如不支持语法高亮显示&#xff0c;不支持代码自动补全等功能。因次&…

18_基于深度学习的烟雾检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)

目录 项目介绍&#x1f3af; 功能展示&#x1f31f; 一、环境安装&#x1f386; 环境配置说明&#x1f4d8; 安装指南说明&#x1f3a5; 环境安装教学视频 &#x1f31f; 二、数据集介绍&#x1f31f; 三、系统环境&#xff08;框架/依赖库&#xff09;说明&#x1f9f1; 系统环…

【计算机网络架构】混合型架构简介

引言在当今数字化浪潮席卷全球的背景下&#xff0c;网络技术正以前所未有的速度迅猛发展&#xff0c;各种网络架构如雨后春笋般涌现。从早期简单的总线型、星型架构&#xff0c;到后来的环型、树型架构&#xff0c;再到如今复杂的网状型、云计算架构等&#xff0c;每一种架构都…

Hexo 双分支部署指南:从原理到 Netlify 实战

Hexo 双分支部署指南&#xff1a;从原理到 Netlify 实战 在 Hexo 博客部署中&#xff0c;很多人会困惑于hexo d自动部署与 GitHub 手动提交的区别&#xff0c;以及如何通过双分支结构优雅地部署到 Netlify。本文将清晰拆解两种部署方式的核心差异&#xff0c;并手把手教你用双分…

【数据结构】深入理解单链表与通讯录项目实现

文章目录一、单链表的概念及结构1.1 什么是单链表&#xff1f;1.2 节点的组成1.3 单链表的特点二、单链表的实现2.1 类型定义2.2 基础工具函数1. 链表打印函数2. 节点创建函数2.3 单链表的核心操作&#xff08;1&#xff09;插入操作1. 尾插&#xff08;SLTPushBack&#xff09…

《Python学习之字典(一):基础操作与核心用法》

坚持用 清晰易懂的图解 代码语言&#xff0c;让每个知识点变得简单&#xff01; &#x1f680;呆头个人主页详情 &#x1f331; 呆头个人Gitee代码仓库 &#x1f4cc; 呆头详细专栏系列 座右铭&#xff1a; “不患无位&#xff0c;患所以立。” Python学习之字典&#xff08;…

[安洵杯 2019]Attack

BUUCTF在线评测BUUCTF 是一个 CTF 竞赛和训练平台&#xff0c;为各位 CTF 选手提供真实赛题在线复现等服务。https://buuoj.cn/challenges#[%E5%AE%89%E6%B4%B5%E6%9D%AF%202019]Attack流量分析题&#xff0c;浏览的时候发现攻击者上传信息页面&#xff0c; 直接搜索 flag 就…