C++ STL的pair和tuple的使用

1、pair的基本使用

1.1 pair概述

pair是C++标准模板库(STL)中的一个模板类,定义在<utility>头文件中。它可以将两个不同类型的值组合成一个单一对象,存储二元组

std::pair 本质上是一个包含两个成员(firstsecond)的结构体

1.2 pair的创建和初始化

#include <utility>
#include <string>
#include <iostream>

int main() {
    // 方法1:使用构造函数
    std::pair<int, std::string> p1(1, "apple");

    // 方法2:使用外部make_pair()方法
    auto p2 = std::make_pair(2, "banana");

    // 方法3:C++11统一初始化,可省略“=”
    std::pair<int, std::string> p3 = {3, "orange"};

    // 方法4:逐个赋值
    std::pair<int, std::string> p4;
    p4.first = 4;
    p4.second = "pear";

    return 0;
}

1.3 pair的常用操作

#include <utility>
#include <iostream>

int main() {
    std::pair<int, std::string> p(1, "apple");

    // 使用first和second变量访问前后两元素
    std::cout << "First: " << p.first << ", Second: " << p.second << std::endl;

    // C++17对结构体的结构化绑定
    auto [id, name] = p;
    std::cout << "ID: " << id << ", Name: " << name << std::endl;

    // 支持比较操作
    std::pair<int, std::string> p2(2, "banana");
    if (p < p2) {
        std::cout << "p is less than p2" << std::endl;
    }

    // 使用swap成员方法来交换两个pair
    std::pair<int, std::string> p3(3, "orange");
    p.swap(p3);

    return 0;
}


2. tuple的基本使用

2.1 tuple概述

tuple是C++11引入的模板类,定义在<tuple>头文件中。它可以存储固定大小的不同类型值的集合,可以看作是pair的泛化版本存储多元组(元素个数大于2个时可以使用)。

std::tuple 通过递归继承和模板元编程实现,其行为类似于一个异构的结构体,但成员数量和类型在编译时动态确定。

2.2 tuple的创建和初始化

#include <tuple>
#include <string>
#include <iostream>

int main() {
    // 方法1:使用构造函数
    std::tuple<int, std::string, double> t1(1, "apple", 3.5);

    // 方法2:使用外部make_tuple()方法
    auto t2 = std::make_tuple(2, "banana", 4.2);

    // 方法3:C++11统一初始化,可省略“=”
    std::tuple<int, std::string, double> t3 = {3, "orange", 2.8};

    // 方法4:使用tie创建引用tuple
    int id;
    std::string name;
    double price;
    std::tie(id, name, price) = t1;

    return 0;
}

2.3 tuple的常用操作

#include <tuple>
#include <string>
#include <iostream>

int main() {
    auto t = std::make_tuple(1, "apple", 3.5);

    // C++11使用外部的get<N>()方法访问元素,无内部访问方法
    std::cout << "ID: " << std::get<0>(t) 
              << ", Name: " << std::get<1>(t)
              << ", Price: " << std::get<2>(t) << std::endl;

    // C++14结构化绑定(C++17更完善)
    auto [id, name, price] = t;
    std::cout << "ID: " << id << ", Name: " << name << ", Price: " << price << std::endl;

    // 支持比较操作
    auto t2 = std::make_tuple(2, "banana", 4.2);
    if (t < t2) {
        std::cout << "t is less than t2" << std::endl;
    }

    // 连接两个tuple
    auto t3 = std::tuple_cat(t, t2);

    return 0;
}


3. pair和tuple的高级使用

3.1 结合容器使用

pairtuple都可以与容器结合,作为容器中的元素,以下为部分示例:

  1. 在vector中使用

    // 使用pair存储坐标点(x,y)
    std::vector> points = {
       {1, 2}, 
       {3, 4}, 
       {5, 6}
    };
    points.emplace_back(7, 8);
    for (const auto& [x, y] : points) { // 结构化绑定遍历访问
       std::cout << "(" << x << ", " << y << ")" << std::endl;
    }
    
    // 使用tuple存储学生信息(学号,姓名,成绩)
    std::vector> students = {
       {101, "Alice", 90.5},
       {102, "Bob", 88.0},
       {103, "Charlie", 92.3}
    };
    students.emplace_back(104, "David", 85.7);
    for (const auto& [id, name, score] : students) { // 结构化绑定遍历访问
       std::cout << id << ": " << name << " - " << score << std::endl;
    }
  2. 在map中使用

    // 使用pair作为map的值
    std::map> product_map = {
       {1, {"Apple", 3.5}},
       {2, {"Banana", 2.8}},
       {3, {"Orange", 4.2}}
    };
    product_map.emplace(4, std::make_pair("Pear", 3.9));
    for (const auto& [id, product] : product_map) { // 结构化绑定遍历
       const auto& [name, price] = product;
       std::cout << id << ": " << name << " @ $" << price << std::endl;
    }
    
    // 使用tuple作为map的值
    std::map> employee_map = {
       {"Alice", {101, 8500.0, "Developer"}},
       {"Bob", {102, 7800.5, "Designer"}}
    };
    if (auto it = employee_map.find("Alice"); it != employee_map.end()) {
       auto& [id, salary, position] = it->second;
       std::cout << "ID: " << id << ", Salary: " << salary << std::endl;
    }
  3. 在priority_queue中使用

    因为优先队列priority_queue是堆排序,使用pairtuple默认按第一元素排序,可以指定排序方法

// 自定义排序方法(按第2元素排序)
auto cmp = [](const auto& a, const auto& b) {
    return std::get<1>(a) < std::get<1>(b); 
};

std::priority_queue<
    std::tuple<int, int, std::string>,
    std::vector<std::tuple<int, int, std::string>>,
    decltype(cmp)> pq(cmp);

3.2 排序操作

pairtuple都支持字典序比较,也就支持排序

  1. pair排序

    std::vector> data = {
       {2, "banana"}, 
       {1, "apple"}, 
       {2, "apple"}
    };
    
    // 默认排序(按first升序,first相同时按second升序)
    std::sort(data.begin(), data.end());
    
    // 自定义排序:按second降序
    std::sort(data.begin(), data.end(), [](const auto& a, const auto& b) {
       return a.second > b.second; 
    });
  2. tuple排序

    std::vector> products = {
       {3, "C", 1.5}, 
       {1, "A", 2.5}, 
       {2, "B", 1.0}
    };
    
    // 默认排序(按第0元素升序)
    std::sort(products.begin(), products.end());
    
    // 自定义排序:按价格(第2元素)降序
    std::sort(products.begin(), products.end(), [](const auto& a, const auto& b) {
       return std::get<2>(a) > std::get<2>(b);
    });

3.3 类型萃取

  1. pair的类型查询

    std::pair p;
    using FirstType = decltype(p)::first_type;  // int
    using SecondType = decltype(p)::second_type; // std::string
  2. tuple的类型萃取

    using MyTuple = std::tuple;
    
    // 获取第1个元素的类型
    using ElementType = std::tuple_element<1, MyTuple>::type; // std::string
    
    // 获取tuple大小
    constexpr size_t size = std::tuple_size::value; // 3
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇