当前位置: 首页 > news >正文

49 C++ STL模板库18-类模板-pair

C++ STL模板库18-类模板-pair

文章目录

  • C++ STL模板库18-类模板-pair
    • 一、本质定义
    • 二、核心作用
    • 三、 用法示例

std::pair 是 C++ 标准库中定义于 <utility> 头文件的模板类,用于将两个不同类型的值组合成单一对象,实现异构数据的关联存储。

一、本质定义

template <class T1, class T2>
struct pair {T1 first;   // 第一个元素 T2 second;  // 第二个元素 
};
  • 二元组结构:存储任意两个类型 T1T2 的值
  • 零开销抽象:编译时确定类型,无运行时性能损耗
  • 标准库基石:被广泛应用于 STL 容器和算法

二、核心作用

  1. 关联异构数据
    将逻辑相关的两个值绑定为单一实体:

    // 坐标点 (x, y)
    std::pair<double, double> point(3.5, 7.2);
    
  2. 函数多返回值
    替代结构体,简化多值返回:

    std::pair<bool, std::string> validateUser(int id) {if (id > 0) return {true, "Valid"};return {false, "Invalid ID"};
    }
    
  3. STL 容器元素

    • std::map/std::unordered_map 的键值对元素:

      std::map<int, std::string> employees = {{101, "Alice"},  // pair<int, string>{102, "Bob"}
      };
      
    • 排序容器中的复合数据:

      std::vector<std::pair<int, std::string>> scores = {{95, "Math"}, {88, "English"}
      };
      std::sort(scores.begin(), scores.end());  // 按int排序 
      
  4. 高效资源传递
    支持移动语义避免拷贝:

    auto createResource() {std::vector<int> data = {1, 2, 3};std::string name = "Data";return std::make_pair(std::move(data), std::move(name));  // 零拷贝返回 
    }
    

三、 用法示例

#include <utility>
#include <string>
#include <iostream>
#include <tuple>
#include <vector>struct Data {Data(int a, double b) : x(a), y(b) {}int x;double y;
};int main() {//1.构造与初始化// 1. 默认构造:成员值初始化std::pair<int, std::string> p1;std::cout << "p1: (" << p1.first  << ", " << p1.second  << ")\n";  // (0, "")// 2. 直接初始化std::pair<int, double> p2(42, 3.14);std::cout << "p2: (" << p2.first  << ", " << p2.second  << ")\n";  // (42, 3.14)// 3. 移动构造std::string s = "hello";std::pair<int, std::string> p3(100, std::move(s));std::cout << "p3: (" << p3.first  << ", " << p3.second  << ")\n";  // (100, "hello")std::cout << "s after move: " << s << "\n";  // ""(空,资源已转移)// 4. 通用构造(完美转发)std::pair<double, long> p4(2.718f, 7);  // float→double, int→longstd::cout << "p4: (" << p4.first  << ", " << p4.second  << ")\n";  // (2.718, 7)// 5. 复制/移动构造(从其他pair)auto p5 = p2;  // 复制auto p6 = std::move(p3);  // 移动// 6. 分段构造(避免冗余拷贝)std::pair<Data, Data> p7(std::piecewise_construct,std::forward_as_tuple(1, 2.0),  // 构造第一个Data: Data(1, 2.0)std::forward_as_tuple(3, 4.0)   // 构造第二个Data: Data(3, 4.0));std::cout << "p7: ((" << p7.first.x  << "," << p7.first.y  << "), ("<< p7.second.x  << "," << p7.second.y  << "))\n";  // ((1,2),(3,4))// 2.赋值操作{// 1. 复制赋值std::pair<int, int> p8(10, 20);auto p9 = p8;  // p9 = (10,20)// 2. 移动赋值std::pair<std::string, std::string> p10("A", "B");std::pair<std::string, std::string> p11;p11 = std::move(p10);  // p11 = ("A","B"), p10变为("","")// 3. 通用赋值(类型转换)std::pair<int, double> src(5, 10.5);std::pair<long, float> dst;dst = src;  // int→long, double→floatstd::cout << "dst: (" << dst.first  << ", " << dst.second  << ")\n"; // (5, 10.5)}//3. 元素访问{std::pair<int, std::string> p(42, "answer");// 1. 直接访问成员p.first  = 100;p.second  = "changed";std::cout << "p: (" << p.first  << ", " << p.second  << ")\n"; // (100, "changed")// 2. 结构化绑定(C++17)auto [num, str] = p;std::cout << "num=" << num << ", str=" << str << "\n"; // num=100, str=changed// 3. 使用 get<N>() 访问auto& x = std::get<0>(p);  // x是first的引用auto& y = std::get<1>(p);  // y是second的引用x = 200;std::cout << "p.first  after get: " << p.first  << "\n"; // 200}//4. 交换操作{std::pair<int, std::string> a(1, "apple");std::pair<int, std::string> b(2, "banana");// 1. 成员函数 swapa.swap(b); std::cout << "a: (" << a.first  << ", " << a.second  << ")\n"; // (2, "banana")std::cout << "b: (" << b.first  << ", " << b.second  << ")\n"; // (1, "apple")// 2. 非成员函数 swapstd::swap(a, b);  // 换回原值std::cout << "a: " << a.first  << ", b: " << b.first  << "\n"; // a:1, b:2}//5. 比较操作{std::pair<int, int> x(1, 2);std::pair<int, int> y(1, 3);std::pair<int, int> z(2, 1);std::cout << (x < y)  << "\n";  //first相等(1==1),second:2<3 → truestd::cout << (x <= y)  << "\n"; //1std::cout << (y > x)  << "\n";  //1std::cout << (z > x)  << "\n";  //1std::cout << (x != std::make_pair(1, 99))  << "\n"; //1std::cout << (x == std::make_pair(1, 2))  << "\n";  //1}//6. 实用函数{// 1. make_pair 自动推导类型auto p = std::make_pair(42, 3.14);  // std::pair<int, double>auto q = std::make_pair("text", 1); // std::pair<const char*, int>// 2. 在容器中使用std::vector<std::pair<int, std::string>> vec;vec.emplace_back(1,  "one");  // 直接构造pair(高效)vec.push_back(std::make_pair(2,  "two"));// 3. 作为函数返回值auto findInMap = [](const auto& map, int key) -> std::pair<bool, decltype(map.begin())>  {auto it = map.find(key); return {it != map.end(),  it};};std::map<int, std::string> m{{1, "a"}, {2, "b"}};auto [found, it] = findInMap(m, 2);if (found) std::cout << "Found: " << it->second << "\n"; // "b"}}
http://www.xdnf.cn/news/1333927.html

相关文章:

  • 解决前端项目启动时找不到esm文件的问题
  • PostgreSQL 流程---更新
  • 力扣面试150(61/100)
  • 使用安卓平板,通过USB数据线(而不是Wi-Fi)来控制电脑(版本1)
  • 笔试——Day44
  • 使用RealSense相机和YOLO进行实时目标检测
  • 从零开发Java坦克大战Ⅱ(上) -- 从单机到联机(架构演进与设计模式剖析)
  • 01.初识mysql数据库,了解sql语句
  • React-native之组件
  • 《算法导论》第 34 章 - NP 完全性
  • J1939协议
  • C++围绕音视频相关的资料都有哪些?如何进行学习
  • 升级Android系统webview
  • 运维日常工作100条
  • linux内核源码下载
  • Redisson3.14.1及之后连接阿里云redis代理模式,使用分布式锁:ERR unknown command ‘WAIT‘
  • 双模式 RTMP H.265 播放器解析:从国内扩展到 Enhanced RTMP 标准的演进
  • 猫头虎开源AI分享|基于大模型和RAG的一款智能text2sql问答系统:SQLBot(SQL-RAG-QABot),可以帮你用自然语言查询数据库
  • PowerShell脚本检查业务健康状态
  • Web3:重构互联网秩序的下一代范式革命
  • OceanBase DBA实战营2期--SQL 关键字限流学习笔记
  • CAT1+mqtt
  • Bigemap APP 详细使用教程,入门学习PPT
  • KDD 2025 | CMA:一次训练,预测任意过去与未来!元学习+扩散模型颠覆时序预测!
  • 【嵌入式电机控制#33】FOC:意法电控驱动层源码解析——整体框架篇(了解,常查阅)
  • 【Day 31】Linux-LNMP
  • 0基础安卓逆向原理与实践:第3章:逆向工程理论基础
  • 8 webUI中-Controlnet(控制与约束)的应用分类与使用方法
  • C++高频知识点(三十一)
  • 【ElasticSearch】ElasticSearch Overview