Modern C++11 常用核心函数完全讲义
C++11 是 C++ 发展史上的里程碑版本(Modern C++ 的起点)。它引入了大量大幅提升开发效率、代码安全性与执行性能的标准库函数。本讲义按照功能分类,详细剖析最常用、最高频的 C++11 函数。
目录
- 一、字符串与数值转换函数族(
<string>) - 二、STL 算法与数值增强函数(
<algorithm>/<numeric>) - 三、通用实用工具函数(
<utility>/<tuple>) - 四、内存与智能指针相关函数(
<memory>) - 五、函数式编程与包装器(
<functional>) - 六、并发与时间控制函数(
<thread>/<chrono>) - 七、核心函数速查表
一、字符串与数值转换函数族(<string>)
在 C++11 之前,数字与字符串互转需要依赖 C 语言的 sprintf/atoi 或低效的 stringstream。C++11 提供了直接的原生转换函数。
1. 数值转字符串:std::to_string
- 功能:将各类整型(
int,long long)及浮点型(float,double)统一转为std::string。
#include <iostream>
#include <string>
int main() {
int a = 123;
double pi = 3.14159;
std::string s1 = std::to_string(a); // "123"
std::string s2 = std::to_string(pi); // "3.141590" (浮点数默认输出6位小数)
std::cout << s1 + "_" + s2 << std::endl;
return 0;
}
2. 字符串转数值:std::stoi, std::stoll, std::stod 等
- 语法原型:
int stoi(const string& str, size_t* pos = 0, int base = 10) pos:记录第一个未解析字符的索引位置(通常传nullptr)。base:进制基数(默认 10 进制,可指定 2、8、16 进制)。
#include <iostream>
#include <string>
int main() {
std::string strInt = "-42";
std::string strHex = "1A"; // 16 进制数
std::string strFloat = "3.1415";
int val = std::stoi(strInt); // -42
long long llVal = std::stoll("98765432100"); // 转 64 位整型
int hexVal = std::stoi(strHex, nullptr, 16); // 按 16 进制解析 -> 26
double dVal = std::stod(strFloat); // 3.1415
std::cout << val << ", " << hexVal << ", " << dVal << std::endl;
return 0;
}
二、STL 算法与数值增强函数
1. 范围谓词三剑客:all_of, any_of, none_of(<algorithm>)
结合 C++11 Lambda 表达式,可以单行替代繁琐的 for 循环检查:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {2, 4, 6, 8, 10};
// 是否全部为偶数?
bool allEven = std::all_of(v.begin(), v.end(), [](int x) { return x % 2 == 0; }); // true
// 是否存在大于 5 的元素?
bool anyGt5 = std::any_of(v.begin(), v.end(), [](int x) { return x > 5; }); // true
// 是否没有任何负数?
bool noNeg = std::none_of(v.begin(), v.end(), [](int x) { return x < 0; }); // true
std::cout << std::boolalpha << allEven << " " << anyGt5 << " " << noNeg << std::endl;
return 0;
}
2. 递增序列填充:std::iota(<numeric>)
- 功能:从给定的起始值开始,为区间内的每个元素依次赋值并递增(常用于并查集初始化、离散化下标生成)。
#include <iostream>
#include <vector>
#include <numeric> // std::iota 在该头文件中
int main() {
std::vector<int> p(5);
std::iota(p.begin(), p.end(), 1); // 填充为: 1, 2, 3, 4, 5
for (int x : p) std::cout << x << " ";
std::cout << std::endl;
return 0;
}
3. 同时获取极值:std::minmax 与 std::minmax_element(<algorithm>)
- 功能:单次扫描同时找出最小值和最大值,减少比较次数。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 1. 获取多个常量的极值 (pair 返回 {min, max})
auto p = std::minmax({3, 1, 4, 1, 5, 9, 2, 6});
std::cout << "Min: " << p.first << ", Max: " << p.second << "\n"; // Min: 1, Max: 9
// 2. 获取容器中的极值迭代器
std::vector<int> v = {10, 30, 20, 50, 40};
auto result = std::minmax_element(v.begin(), v.end());
std::cout << "Min element: " << *result.first
<< ", Max element: " << *result.second << "\n"; // 10, 50
return 0;
}
4. 有序性与划分检查:is_sorted(<algorithm>)
std::vector<int> v = {1, 3, 2};
bool sorted = std::is_sorted(v.begin(), v.end()); // false
三、通用实用工具函数(<utility> / <tuple>)
1. 现代移动语义:std::move 与 std::forward
std::move:本质是无条件的强制类型转换,将左值转为右值引用,触发移动构造或移动赋值,避免深拷贝。std::forward:完美转发(Perfect Forwarding),在模板泛型编程中保持原参数的左右值属性。
#include <iostream>
#include <vector>
#include <string>
#include <utility>
int main() {
std::string str = "Huge Content...";
std::vector<std::string> vec;
vec.push_back(std::move(str)); // 转移内部指针所有权,0 拷贝开销
// 此处 str 被掏空,变为未指定状态(空字符串)
std::cout << "str size after move: " << str.size() << std::endl; // 0
return 0;
}
2. 元组与解包:std::make_tuple, std::tie, std::ignore
C++11 引入了多元组 std::tuple(std::pair 的泛化版本)。
#include <iostream>
#include <tuple>
#include <string>
// 函数返回多个不同类型的值
std::tuple<int, std::string, double> getUserInfo() {
return std::make_tuple(101, "Alice", 95.5);
}
int main() {
int id;
std::string name;
double score;
// 使用 std::tie 批量解包绑定到局部变量
std::tie(id, name, score) = getUserInfo();
// 使用 std::ignore 忽略不关心的返回值
std::tie(id, std::ignore, score) = getUserInfo();
std::cout << id << ": " << name << " -> " << score << std::endl;
return 0;
}
3. 支持初始化列表的 std::min / std::max
在 C++11 之前只能比较两个数 min(a, b),C++11 开始原生支持大括号多值比较:
int smallest = std::min({5, 2, 8, 1, 9}); // 直接返回 1
int largest = std::max({5, 2, 8, 1, 9}); // 直接返回 9
四、内存与智能指针相关函数(<memory>)
C++11 正式引入了现代智能指针系统(std::unique_ptr, std::shared_ptr, std::weak_ptr),彻底告别悬空指针与手动 delete。
1. std::make_shared
- 功能:安全、高效地构造
std::shared_ptr。 - 优势:将控制块(Control Block)与用户对象合并在一次堆内存分配中完成,避免了两次
new的开销,且保证了异常安全。
#include <iostream>
#include <memory>
struct Node {
int val;
Node(int v) : val(v) {}
};
int main() {
// ✅ 推荐的 C++11 构造方式
auto ptr1 = std::make_shared<Node>(100);
// ❌ 不推荐的传统方式
// std::shared_ptr<Node> ptr2(new Node(100));
std::cout << "Node value: " << ptr1->val
<< ", Ref count: " << ptr1.use_count() << std::endl;
return 0;
}
(注:std::make_unique 是在 C++14 才被补充加入标准库,但在 C++11 中可以直接使用 std::unique_ptr<Node>(new Node(100)))。
五、函数式编程与包装器(<functional>)
1. 通用函数封装:std::function 与 std::bind
std::function:可调用对象包装器(能存储普通函数、函数指针、Lambda 表达式、仿函数等)。std::bind:参数绑定器,用于固定函数的某几个参数,或者调整参数传递顺序。
#include <iostream>
#include <functional>
int add(int a, int b) {
return a + b;
}
int main() {
// 1. std::function 包装 Lambda
std::function<int(int, int)> op = [](int a, int b) { return a * b; };
std::cout << "Lambda: " << op(3, 4) << std::endl; // 12
// 2. std::bind 绑定参数 (使用 std::placeholders 占位符)
using namespace std::placeholders;
// 将 add 函数的第一个参数固定为 10,生成新的单参数函数 add10
auto add10 = std::bind(add, 10, _1);
std::cout << "Bind add10(5): " << add10(5) << std::endl; // 15
return 0;
}
六、并发与时间控制函数(<thread> / <chrono>)
1. 线程控制:std::this_thread::sleep_for 与 get_id
C++11 终于拥有了跨平台的原生多线程库。
#include <iostream>
#include <thread>
#include <chrono>
int main() {
std::cout << "当前主线程 ID: " << std::this_thread::get_id() << std::endl;
std::cout << "正在休眠 500 毫秒...\n";
// 配合 <chrono> 精确控制跨平台休眠
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "休眠结束!\n";
return 0;
}
2. 高精度计时:std::chrono::high_resolution_clock::now()
测量代码执行耗时的标准 Modern C++ 手段:
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
// 模拟一段耗时计算
long long sum = 0;
for (int i = 0; i < 1000000; ++i) sum += i;
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "计算耗时: " << elapsed.count() << " 毫秒\n";
return 0;
}
七、核心函数速查表
| 所属头文件 | 常用函数 | 主要功能 / 特性 | 常见应用场景 |
|---|---|---|---|
<string> |
to_string(val) |
将数字转为 std::string |
字符串拼接、格式化输出 |
<string> |
stoi / stoll / stod |
字符串解析为整型 / 浮点型 | 文本解析、输入流处理 |
<algorithm> |
all_of / any_of / none_of |
结合 Lambda 进行全范围谓词判定 | 状态合法性检查、过滤 |
<algorithm> |
minmax / minmax_element |
一次遍历同时求出最小值与最大值 | 性能优化、区间统计 |
<algorithm> |
is_sorted |
检查序列是否已经升序排列 | 断言、前置条件检验 |
<numeric> |
iota(begin, end, val) |
生成等差递增数列填入容器 | 并查集初始化、索引数组 |
<utility> |
move(obj) |
将左值强制转为右值引用 | 避免深拷贝、高效资源转移 |
<utility> |
min({a, b, c...}) |
接收初始化列表多值取极小 | 动态规划多状态转移 |
<tuple> |
make_tuple / tie |
打包与解包多返回值 | 函数返回多个异构结果 |
<memory> |
make_shared<T>(args) |
安全且高效地创建共享智能指针 | 现代 C++ 内存管理 |
<functional> |
bind / function |
函数包装与偏函数参数绑定 | 回调函数注册、事件分发 |
<thread> |
this_thread::sleep_for |
跨平台高精度阻塞休眠 | 任务轮询、延时等待 |
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com