C++标准库头文件 utility 举例说明

C++标准库头文件 utility 举例说明

1. <utility>

<utility> 是 C++ 标准库头文件,提供 基础工具类与函数,主要包括 std::pair、std::move、std::forward、std::swap 等核心功能。以下是详细说明及代码示例:

1. std::pair:存储两个值的容器

基本用法

#include <utility>
#include <iostream>

int main() {
    // 创建 pair
    std::pair<int, std::string> student(1, "Alice");

    // 访问元素
    std::cout << "ID: " << student.first << ", Name: " << student.second << "\n";

    // 结构化绑定(C++17)
    auto [id, name] = student;
    std::cout << "ID: " << id << ", Name: " << name << "\n";

    return 0;
}

==============================================================
输出:
ID: 1, Name: Alice
ID: 1, Name: Alice
==============================================================
用途:存储键值对(如 map 的元素)、函数多返回值。

工厂函数 std::make_pair

auto point = std::make_pair(3.14, 2.71);  // 自动推导类型


2. std::move:转换为右值引用(启用移动语义)
移动资源(避免拷贝)

#include <utility>
#include <vector>

int main() {
    std::vector<int> src = {1, 2, 3};
    std::vector<int> dest = std::move(src);  // 移动构造

    std::cout << "src size: " << src.size() << "\n";  // 0(资源已转移)
    std::cout << "dest size: " << dest.size() << "\n"; // 3
    return 0;
}

关键点:
std::move 将对象标记为“可移动”,调用移动构造函数/赋值运算符。
被移动后的对象处于有效但未定义状态(如 src 为空)。

3. std::forward:完美转发(保持值类别)
保持左值/右值属性

#include <utility>
#include <iostream>

template<typename T>
void wrapper(T&& arg) {
    process(std::forward<T>(arg));  // 完美转发
}

void process(int& x) { std::cout << "Lvalue: " << x << "\n"; }
void process(int&& x) { std::cout << "Rvalue: " << x << "\n"; }

int main() {
    int a = 10;
    wrapper(a);       // 传递左值 → 调用 process(int&)
    wrapper(20);      // 传递右值 → 调用 process(int&&)
    return 0;
}

==========================================================
Lvalue: 10
Rvalue: 20
==========================================================
用途:在模板函数中保持参数原始类型(左值/右值)。

4. std::swap:交换两个对象的值
高效交换

#include <utility>
#include <vector>

int main() {
    std::vector<int> vec1 = {1, 2, 3};
    std::vector<int> vec2 = {4, 5};

    std::swap(vec1, vec2);  // 交换内容

    // vec1 = {4, 5}, vec2 = {1, 2, 3}
    return 0;
}

底层优化:对标准库容器(如 vector)通常为 O(1) 时间复杂度(交换指针)。

5. std::exchange:赋值并返回旧值
原子性操作模拟

#include <utility>
#include <iostream>

int main() {
    int x = 10;
    int old_x = std::exchange(x, 20);  // x=20,返回旧值10

    std::cout << "old_x: " << old_x << ", x: " << x << "\n";
    return 0;
}

========================================================
输出:
old_x: 10, x: 20
用途:状态机更新、线程安全编程。
========================================================

6. std::as_const:转换为常量引用(C++17)
防止意外修改

#include <utility>

void print(const std::string& s) {
    // s 不能被修改
}

int main() {
    std::string text = "Hello";
    print(std::as_const(text));  // 显式传递 const 引用
    return 0;
}


总结: 核心功能

工具 用途 典型场景
std::pair 存储两个值 多返回值、键值对临时存储
std::move 启用移动语义 资源转移(避免深拷贝)
std::forward 完美转发 通用引用(T&&)参数传递
std::swap 高效交换对象内容 容器操作、排序算法
std::exchange 赋值并返回旧值 状态更新、原子操作模拟
std::as_const 添加 const 限定 强制只读访问

进阶技巧

  • 结合结构化绑定(C++17):

    auto [min, max] = std::minmax({3, 1, 4});  // min=1, max=4
    
  • 自定义 swap:

    struct Widget { int data; };
    void swap(Widget& a, Widget& b) {
    	std::swap(a.data, b.data);  // 提供自定义交换
    }
    
posted @ 2025-04-28 14:55  michaelchengjl  阅读(127)  评论(0)    收藏  举报