news 2026/4/10 13:15:09

【C++】Pair实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++】Pair实现

C++20 Pair 实现详解

代码概览

这是一个模仿std::pair的现代 C++20 实现,使用了 concepts、完美转发等特性。

关键点

1. 默认成员初始化器

T1 first{};T2 second{};

为什么用{}

写法Pair<int, int> p;的结果
T1 first;first是垃圾值
T1 first{};first0

{}确保值初始化,基本类型会被初始化为零。

2. 默认构造函数的约束

constexprPair()requires(std::default_initializable<T1>&&std::default_initializable<T2>)=default;

作用:只有当T1T2都可以默认构造时,Pair才能默认构造。

structNoDefault{NoDefault(int){}// 没有默认构造函数};Pair<NoDefault,int>p1;// 编译错误,清晰的错误信息Pair<NoDefault,int>p2(NoDefault(1),2);// OK

3. 转发构造函数

template<typenameU1,typenameU2>constexprPair(U1&&x,U2&&y):first(std::forward<U1>(x)),second(std::forward<U2>(y)){}

关键概念:万能引用 vs 右值引用

template<typenameT>voidfoo(T&&x);// T 在此处推导 → 万能引用template<typenameT>structBar{voidbaz(T&&x);// T 已经固定 → 右值引用};

为什么用std::forward

Pair<Counter,Counter>p1(c,c);// c 是左值 → 拷贝Pair<Counter,Counter>p2(std::move(c),Counter(10));// 右值 → 移动

std::forward保持参数的值类别(左值/右值)。

4. 转换构造函数的约束

template<typenameU1,typenameU2>requires(!std::same_as<Pair<U1,U2>,Pair<T1,T2>>)constexprPair(constPair<U1,U2>&other)

为什么需要这个约束?

防止与拷贝构造函数冲突:

Pair<int,int>p1(1,2);Pair<int,int>p2(p1);// 应该调用拷贝构造函数,不是转换构造函数

如果没有约束,两个构造函数都匹配,可能导致歧义。

5.= default的含义

Pair(constPair&)=default;

意思:让编译器生成默认实现。

注意:= default不等于 “初始化所有成员为零”,而是 “做编译器默认会做的事”。

structS{intx;S()=default;};S s1;// x 是垃圾值(默认初始化)S s2{};// x 是 0(值初始化)

6.make_pair使用std::decay_t

template<typenameT1,typenameT2>constexprPair<std::decay_t<T1>,std::decay_t<T2>>make_pair(T1&&x,T2&&y)

为什么?

输入类型std::decay_t结果
int&int
const int&int
int[10]int*
int(double)int(*)(double)

避免存储引用或数组类型:

inta=1;autop=make_pair(a,2);// Pair<int, int>,不是 Pair<int&, int>

7. Swap 的 ADL 技巧

voidswap(Pair&other)noexcept{usingstd::swap;// 引入 std::swap 作为后备swap(first,other.first);// ADL 会找到更好的重载swap(second,other.second);}

如果T1有自定义的swap,会优先使用它。

总结表

构造函数用途关键点
Pair()默认构造需要约束default_initializable
Pair(U1&&, U2&&)从任意值构造完美转发
Pair(const Pair&)拷贝= default
Pair(Pair&&)移动= default
Pair(const Pair<U1,U2>&)转换拷贝需要排除相同类型
Pair(Pair<U1,U2>&&)转换移动需要排除相同类型
#include<concepts>#include<type_traits>#include<utility>template<typenameT1,typenameT2>structPair{T1 first{};T2 second{};// ConstructorsconstexprPair()requires(std::default_initializable<T1>&&std::default_initializable<T2>)=default;// Defaulttemplate<typenameU1,typenameU2>constexprPair(U1&&x,U2&&y):first(std::forward<U1>(x)),second(std::forward<U2>(y)){}// ForwardingPair(constPair&)=default;// CopyPair(Pair&&)=default;// Movetemplate<typenameU1,typenameU2>requires(!std::same_as<Pair<U1,U2>,Pair<T1,T2>>)constexprPair(constPair<U1,U2>&other):first(other.first),second(other.second){}// Converting copytemplate<typenameU1,typenameU2>requires(!std::same_as<Pair<U1,U2>,Pair<T1,T2>>)constexprPair(Pair<U1,U2>&&other):first(std::move(other.first)),second(std::move(other.second)){}// Converting move// AssignmentPair&operator=(constPair&other)=default;Pair&operator=(Pair&&other)noexcept=default;template<typenameU1,typenameU2>requires(!std::same_as<Pair<U1,U2>,Pair<T1,T2>>)Pair&operator=(constPair<U1,U2>&other){first=other.first;second=other.second;return*this;}template<typenameU1,typenameU2>requires(!std::same_as<Pair<U1,U2>,Pair<T1,T2>>)Pair&operator=(Pair<U1,U2>&&other){first=std::move(other.first);second=std::move(other.second);return*this;}// Swapvoidswap(Pair&other)noexcept{usingstd::swap;swap(first,other.first);swap(second,other.second);}// Comparison (C++20)booloperator==(constPair&other)const=default;autooperator<=>(constPair&other)const=default;};// Helper functionstemplate<typenameT1,typenameT2>constexprPair<std::decay_t<T1>,std::decay_t<T2>>make_pair(T1&&x,T2&&y){returnPair<std::decay_t<T1>,std::decay_t<T2>>(std::forward<T1>(x),std::forward<T2>(y));}template<typenameT1,typenameT2>voidswap(Pair<T1,T2>&a,Pair<T1,T2>&b)noexcept{a.swap(b);}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/7 15:01:10

Tooll 3视觉编程系统:构建下一代动态图形创作平台

Tooll 3视觉编程系统&#xff1a;构建下一代动态图形创作平台 【免费下载链接】t3 Tooll 3 is an open source software to create realtime motion graphics. 项目地址: https://gitcode.com/GitHub_Trending/t3/t3 在数字艺术创作领域&#xff0c;实时图形处理技术正经…

作者头像 李华
网站建设 2026/4/9 20:34:43

5分钟掌握open-eBackup:从零开始的数据保护实战指南

5分钟掌握open-eBackup&#xff1a;从零开始的数据保护实战指南 【免费下载链接】open-eBackup open-eBackup是一款开源备份软件&#xff0c;采用集群高扩展架构&#xff0c;通过应用备份通用框架、并行备份等技术&#xff0c;为主流数据库、虚拟化、文件系统、大数据等应用提供…

作者头像 李华
网站建设 2026/4/10 10:05:39

Unity Script Collection完整指南:免费脚本资源库实用解析

Unity Script Collection完整指南&#xff1a;免费脚本资源库实用解析 【免费下载链接】Unity-Script-Collection A maintained collection of useful & free unity scripts / librarys / plugins and extensions 项目地址: https://gitcode.com/gh_mirrors/un/Unity-Scr…

作者头像 李华
网站建设 2026/3/28 17:27:32

开源项目合规风险实战手册:从案例剖析到安全架构设计

开源项目合规风险实战手册&#xff1a;从案例剖析到安全架构设计 【免费下载链接】chatlog 项目地址: https://gitcode.com/gh_mirrors/chat/chatlog 当chatlog项目因合规问题突然消失在开发者视野中&#xff0c;整个技术圈都在思考&#xff1a;下一个会是谁&#xff1…

作者头像 李华
网站建设 2026/4/3 1:54:36

星火应用商店终极指南:Linux应用管理的革命性解决方案

星火应用商店终极指南&#xff1a;Linux应用管理的革命性解决方案 【免费下载链接】星火应用商店Spark-Store 星火应用商店是国内知名的linux应用分发平台&#xff0c;为中国linux桌面生态贡献力量 项目地址: https://gitcode.com/spark-store-project/spark-store 还在…

作者头像 李华