std::pair是C++标准库中轻量、固定大小的二元组类型,本质为含public成员first和second的结构体,不支持扩容或查找;定义需显式指定两个模板参数,初始化方式包括默认构造、列表初始化、make_pair和聚合初始化,支持结构化绑定,但不可重新绑定类型,多元素场景应改用tuple或自定义结构体。

直接说结论: std::pair 是 C++ 标准库中轻量、固定大小的二元组类型,适合临时组合两个不同类型(或相同类型)的值;它不支持动态扩容、不提供查找接口,本质就是两个公开成员 first 和 second 的结构体。
如何定义和初始化 pair
定义时必须显式指定两个模板参数类型,不能省略;初始化方式灵活,但构造时机决定是否调用移动/拷贝构造:
- 默认构造:
std::pair<int, std::string> p1;
→first为0,second为空字符串(调用各自默认构造) - 直接列表初始化(推荐,C++11 起):
std::pair<int, const char*> p2{42, "hello"};→ 避免隐式类型转换,不发生临时对象构造 - 使用
std::make_pair(类型推导友好):auto p3 = std::make_pair(3.14, 'x');
→ 推出类型为std::pair<double char></double>;注意:若传入左值,可能意外产生拷贝(比如std::make_pair(s, s)中s是std::string,会拷贝两次) - 聚合初始化(C++17 起支持,等价于列表初始化):
std::pair p4{100, std::string("ok")};→ 类型自动推导,且支持移动语义(std::string("ok")是右值,直接移动)
赋值与修改 first/second 成员
std::pair 的 first 和 second 是 public 成员,可直接读写;赋值操作符是逐成员赋值,不涉及额外逻辑:
- 不能整体“重新绑定”类型或大小,只能改值:
p2.first = 99; p2.second = "world";
- 支持结构化绑定(C++17),解包更直观:
auto [a, b] = p3; // a 是 double, b 是 char
→ 注意:绑定的是拷贝,如需引用,写成auto& [a, b] = p3; - 赋值时若右侧类型不匹配,会发生隐式转换(如有):
p1 = std::make_pair(5L, std::string("test"));→long转int(可能截断),std::string转std::string(拷贝)
常见误用与坑点
看似简单,但在容器、函数传参、模板推导中容易出错:
立即学习“C++免费学习笔记(深入)”;
- 往
std::vector<:pair int>></:pair>中push_back({1, 2})可能失败(老编译器不支持聚合初始化)→ 改用emplace_back(1, 2)或push_back(std::make_pair(1, 2)) -
std::pair<const int std::string></const>中first是 const,无法后续修改:std::pair<const int, std::string> p{1, "a"}; p.first = 2; // 编译错误 - 作为
std::map的 value 类型没问题,但作为 key 时要注意:若second是自定义类且未定义operator<,会导致 map 编译失败(因为std::pair的比较依赖两个成员的<) - 返回局部
pair没问题(RVO/NRVO 通常生效),但别返回指向其成员的指针或引用——first和second生命周期只到 pair 本身结束
最常被忽略的一点:当你需要三个及以上元素时,别硬套 pair<pair>, V></pair>,可读性差、嵌套深、访问啰嗦;该换 std::tuple 或自定义结构体了。











