news 2026/5/7 7:59:52

【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/5/4 4:44:37

实战指南:5步构建高效GIS机器学习流水线

实战指南&#xff1a;5步构建高效GIS机器学习流水线 【免费下载链接】awesome-gis &#x1f60e;Awesome GIS is a collection of geospatial related sources, including cartographic tools, geoanalysis tools, developer tools, data, conference & communities, news,…

作者头像 李华
网站建设 2026/5/4 18:39:51

虚拟演唱会节目单生成

虚拟演唱会节目单生成&#xff1a;基于 ms-swift 的大模型工程化实践 在一场虚拟演唱会上&#xff0c;观众点击“怀旧迪斯科”主题按钮的瞬间&#xff0c;系统便自动推送了一份90分钟的定制化节目单——开场是《I Wanna Dance with Somebody》点燃气氛&#xff0c;中场穿插《Ta…

作者头像 李华
网站建设 2026/5/1 14:05:50

Symfony DomCrawler:轻松实现HTML文档解析与表单处理的PHP神器

Symfony DomCrawler&#xff1a;轻松实现HTML文档解析与表单处理的PHP神器 【免费下载链接】dom-crawler Eases DOM navigation for HTML and XML documents 项目地址: https://gitcode.com/gh_mirrors/do/dom-crawler 你是否曾经为处理HTML文档而头疼&#xff1f;面对复…

作者头像 李华
网站建设 2026/5/2 8:45:48

基于Keil的蜂鸣器实验:入门级项目实践

从“滴”一声开始&#xff1a;用Keil点亮你的第一个嵌入式声音信号你有没有过这样的经历&#xff1f;按下电饭煲的开关&#xff0c;它“嘀”地响一声告诉你已启动&#xff1b;门禁刷卡失败时&#xff0c;“嘀——嘀嘀”两声急促提示音立刻响起。这些看似简单的提示音背后&#…

作者头像 李华
网站建设 2026/5/1 20:34:49

ThinkPad X230黑苹果终极教程:从零开始轻松安装macOS

ThinkPad X230黑苹果终极教程&#xff1a;从零开始轻松安装macOS 【免费下载链接】X230-Hackintosh READMEs, OpenCore configurations, patches, and notes for the Thinkpad X230 Hackintosh 项目地址: https://gitcode.com/gh_mirrors/x2/X230-Hackintosh 想要在经典…

作者头像 李华
网站建设 2026/5/3 11:43:59

Sudachi模拟器完全手册:多平台终极安装与优化指南

Sudachi模拟器完全手册&#xff1a;多平台终极安装与优化指南 【免费下载链接】sudachi Sudachi is a Nintendo Switch emulator for Android, Linux, macOS and Windows, written in C 项目地址: https://gitcode.com/GitHub_Trending/suda/sudachi Sudachi是一款基于C…

作者头像 李华