Skip to content

Ch 17: 参考资源

  • 获取可靠的 C++ 参考资料
  • 了解推荐的学习路径
  • 掌握常用速查表
  • 发现社区和工具资源
资源链接说明
cppreferencehttps://en.cppreference.com/C++ 标准库最权威参考
ISO C++https://isocpp.org/C++ 标准官方来源
C++ Core Guidelineshttps://isocpp.github.io/CppCoreGuidelines/Bjarne Stroustrup 和 Herb Sutter 编写的最佳实践指南
C++ Working Papershttps://wg21.link/C++ 标准委员会工作文档

cppreference 是 C++ 开发者最重要的参考资料:

cppreference 结构:
├── C++ 教程
│ └── 入门教程(覆盖基础)
├── 语言参考
│ ├── 关键词
│ ├── 预处理器
│ ├── 表达式
│ └── 语句
├── 标准库参考
│ ├── <algorithm>
│ ├── <vector>
│ ├── <string>
│ └── ...(所有 STL 容器和函数)
└── 工具和扩展

查找函数用法:

1. 打开 cppreference.com
2. 在搜索框输入函数名(如 std::sort)
3. 查看函数签名、参数说明、返回值
4. 阅读"Possible implementation"了解实现
5. 查看示例代码

C++ Core Guidelines 提供了现代 C++ 编程的权威指导:

// 来自 Core Guidelines 的重要规则示例
// P:必须使用初始化
int x = 0; // ✓ 正确
// int x; // ✗ 错误:未初始化
// C.47:优先使用类初始化列表
class Widget {
int member_{0}; // ✓ 默认成员初始化器
};
// C.80-81:使用 std::variant 代替联合体
// C.81:使用 std::variant(带类型安全的联合体)
// ES.20:总是初始化对象
int a = 0;
int* p = nullptr;
// ES.21:不要在变量定义之间引入可能抛出异常的操作
// ✗ 错误
int x = 42; // OK
int y = function(); // 可能抛异常
int z = x + y; // 这里初始化时 y 可能已构造失败
// F.50:如果函数不需要修改对象,使用 T& 或 const T&
// ✓ 当需要多态或避免拷贝时使用引用
// R.10:避免 malloc 和 free
// ✓ 使用 new/delete 或智能指针
// R.11:优先使用 make_unique 和 make_shared
// I.23:保持较小的函数参数数量(4个以内)
阶段书籍适合人群
入门《C++ Primer》 (Stanley Lippman)完全没有编程经验或从其他语言转来
入门《A Tour of C++》 (Bjarne Stroustrup)有编程经验,想快速了解现代 C++
进阶《Effective C++》 (Scott Meyers)已入门,想写出高质量代码
进阶《Effective Modern C++》 (Scott Meyers)使用 C++11/14/17,想掌握现代特性
高级《Effective STL》 (Scott Meyers)想精通 STL
高级《C++ Concurrency in Action》 (Anthony Williams)想掌握多线程编程
高级《The C++ Programming Language》 (Bjarne Stroustrup)全面深入理解 C++

《C++ Primer》:

  • 全面覆盖 C++ 语言和标准库
  • 包含 C++11/14/17 新特性
  • 每章有练习题
  • 适合系统学习

《Effective Modern C++》:

// 来自本书的关键条款示例
// Item 5: 优先使用 auto 而非显式类型声明
auto i = 42; // ✓ 自动推导
int j = 42; // 冗余
// Item 21: 优先使用 std::make_unique 和 std::make_shared
auto up = std::make_unique<int>(42); // ✓ 推荐
std::unique_ptr<int> up2(new int(42)); // 不推荐
// Item 31: 避免默认捕获模式
// lambda 捕获 this
class Widget {
public:
void add() {
// ✗ 默认按引用捕获 this(危险)
auto f = [=] { return x_; }; // 实际上捕获了 this->x_
// ✓ 使用显式捕获
auto f2 = [self = this] { return self->x_; };
}
private:
int x_;
};

《C++ Concurrency in Action》:

// 来自本书的线程安全示例
#include <mutex>
#include <stdexcept>
class ThreadSafeCounter {
private:
int count_ = 0;
mutable std::mutex mtx_;
public:
int get() const {
std::lock_guard<std::mutex> lock(mtx_);
return count_;
}
void increment() {
std::lock_guard<std::mutex> lock(mtx_);
++count_;
}
};
平台链接说明
learncpp.comhttps://www.learncpp.com/免费 C++ 教程,适合入门
cppreferencehttps://en.cppreference.com/标准库参考
Stack Overflowhttps://stackoverflow.com/questions/tagged/c%2b%2b问题解答
C++ Subreddithttps://reddit.com/r/cpp社区讨论
C++ Discordhttps://discord.gg/cpp实时社区
工具链接用途
Compiler Explorerhttps://godbolt.org/在线查看汇编输出
C++ Insightshttps://cppinsights.io/可视化模板推导
Wandboxhttps://wandbox.org/多编译器在线运行
C++ Shellhttps://cpp.sh/快速实验代码

Compiler Explorer(godbolt.org)是理解 C++ 代码生成的神器:

// 输入代码
#include <vector>
std::vector<int> filter_even(const std::vector<int>& v) {
std::vector<int> result;
for (int x : v) {
if (x % 2 == 0) result.push_back(x);
}
return result;
}
// 查看编译器输出:
// 1. 选择编译器(GCC、Clang、MSVC)
// 2. 查看生成的汇编代码
// 3. 比较不同优化级别(-O0 vs -O2 vs -O3)
// 4. 理解代码实际执行
需要顺序存储?
├─ 是 → 主要在哪里插入/删除?
│ ├─ 尾部 → std::vector
│ ├─ 两端 → std::deque
│ └─ 中间 → std::list 或 std::vector(考虑移动成本)
└─ 否 → 需要键值映射?
├─ 是 → 需要有序键?
│ ├─ 是 → std::map
│ └─ 否 → std::unordered_map
└─ 否 → 需要唯一性?
├─ 是 → 需要有序?
│ ├─ 是 → std::set
│ └─ 否 → std::unordered_set
└─ 否 → 固定大小?
└─ 是 → std::array 或 std::tuple
容器随机访问插入头部插入尾部中间插入查找内存连续
std::vectorO(1)O(n)O(1)*O(n)O(n)✓
std::dequeO(1)O(1)O(1)O(n)O(n)✗
std::listO(n)O(1)O(1)O(1)O(n)✗
std::set---O(log n)O(log n)✗
std::unordered_set---O(1)*O(1)✗
std::map---O(log n)O(log n)✗
std::unordered_map---O(1)*O(1)✗

*均摊复杂度

操作std::vectorstd::liststd::setstd::unordered_set
查找O(n)O(n)O(log n)O(1) 均摊
插入O(n)*O(1)O(log n)O(1) 均摊
删除O(n)O(1)**O(log n)O(1) 均摊
排序迭代O(n log n)O(n log n)O(n)O(n)
顺序遍历O(n)O(n)O(n)O(n)

*均摊复杂度 **给定迭代器位置

#include <algorithm>
#include <vector>
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
// 查找
auto it = std::find(v.begin(), v.end(), 4); // 找元素
auto it = std::find_if(v.begin(), v.end(), [](int x) { return x > 3; });
auto it = std::lower_bound(v.begin(), v.end(), 4); // 二分查找(需已排序)
// 排序
std::sort(v.begin(), v.end()); // 升序
std::sort(v.begin(), v.end(), std::greater<int>()); // 降序
std::stable_sort(v.begin(), v.end()); // 稳定排序
// 操作
std::reverse(v.begin(), v.end()); // 反转
std::unique(v.begin(), v.end()); // 去重(需先排序)
std::shuffle(v.begin(), v.end(), rng); // 洗牌
// 计算
int sum = std::accumulate(v.begin(), v.end(), 0);
int count = std::count_if(v.begin(), v.end(), [](int x) { return x > 3; });
auto [min_it, max_it] = std::minmax_element(v.begin(), v.end());
// 变换
std::transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });
std::copy_if(v.begin(), v.end(), std::back_inserter(result), [](int x) { return x > 3; });
#include <string>
std::string s = " Hello, World! ";
// 大小和容量
s.size(); s.length(); // 字符数
s.capacity(); // 底层容量
s.reserve(100); // 预分配容量
s.shrink_to_fit(); // 释放多余容量
// 访问
s[0]; s.front(); // 第一个字符
s.back(); // 最后一个字符
s.at(i); // 带边界检查
// 修改
s += "extra"; // 追加
s.append("more"); // 追加
s.insert(0, "pre"); // 插入
s.erase(5, 3); // 删除
s.replace(0, 5, "replacement"); // 替换
// 查找
s.find("World"); // 找子串位置
s.rfind("o"); // 反向查找
s.find_first_of("aeiou"); // 找任意元音
s.find_last_of(".!"); // 找最后一个指定字符
// 子串
s.substr(7, 5); // "World"
// 转换
s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end()); // 去空白
std::stoi(s); std::to_string(42); // 数字转换
// C++20
std::string_view sv = s | std::views::drop(2) | std::views::take(5); // 视图
场景推荐原因
单一所有者std::unique_ptr最安全、最高效
共享所有权std::shared_ptr引用计数
观察但不拥有std::weak_ptr避免循环引用
动态数组std::unique_ptr<T[]>数组特化
缓存std::weak_ptr临时引用
插件系统std::shared_ptr共享但可卸载
// 选择指南示例代码
// ✓ 单一所有权 - unique_ptr
auto resource = std::make_unique<Resource>();
process(std::move(resource));
// resource 现在为空,process 负责释放
// ✓ 共享所有权 - shared_ptr
auto cache = std::make_shared<LargeData>();
auto view1 = cache;
auto view2 = cache;
// 所有 shared_ptr 销毁后才释放
// ✓ 打破循环 - weak_ptr
class Parent {
public:
std::weak_ptr<Child> child; // 不增加引用计数
};
// ✓ 错误示例:循环引用
// class A { std::shared_ptr<B> b; };
// class B { std::shared_ptr<A> a; }; // 内存泄漏!
#include <algorithm>
#include <vector>
std::vector<int> v = {1, 2, 3, 4, 5};
// 基本语法
auto f1 = [](int x) { return x * 2; }; // 无捕获
auto f2 = [x](int y) { return x + y; }; // 按值捕获 x
auto f3 = [&x](int y) { x = y; return x; }; // 按引用捕获
auto f4 = [=]() { return x + y; }; // 按值捕获所有
auto f5 = [&]() { return x + y; }; // 按引用捕获所有
// mutable
int count = 0;
auto counter = [count]() mutable { return ++count; };
// 返回类型
auto f6 = [](int x) -> double { return x / 2.0; };
// 标准库算法中使用
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
std::all_of(v.begin(), v.end(), [](int x) { return x > 0; });
// C++14 泛型 lambda
auto generic = [](auto x) { return x * 2; };
// C++11/14 核心特性
auto x = 42; // 类型推导
decltype(x) y = 0; // decltype
auto fn = []() {}; // lambda
std::make_unique<T>(); // make_unique
std::make_shared<T>(); // make_shared
std::move(x); // 移动语义
std::thread t(fn); // 线程
std::mutex m; // 互斥锁
std::lock_guard lock(m); // RAII 锁
// C++17 核心特性
if (auto it = m.find(key); it != m.end()) { // if initializer
// 使用 it
}
std::optional<T>; // 可选值
std::variant<T, U>; // 联合体
std::string_view; // 非拥有字符串视图
std::any; // 任意类型
if constexpr (condition) {} // constexpr if
// C++20 核心特性
auto r = v | views::filter(f); // Ranges
std::format("{}", x); // 格式化
concept C = ...; // Concepts
consteval int f() {} // 立即函数
std::erase_if(v, pred); // 容器的通用 erase
module; export module; // Modules
auto operator<=>(const T&) = default; // 宇宙飞船运算符
资源链接更新频率
C++ WeeklyYouTube: C++ Weekly每周
CppConYouTube: CppCon年度会议
Meeting C++YouTube: Meeting C++定期
C++ Standard Bloghttps://wg21.link/blog标准更新
Terminal window
# C++ 标准工作文档
https://wg21.link/
P0595R2 - constexpr std:: allocator
P1206R4 - std::ranges::to
P0323R12 - std::expected
  • cppreference.com 是最权威的标准库参考
  • C++ Core Guidelines 提供编程最佳实践
  • 系统化学习推荐书籍,速查表帮助日常开发
  • Compiler Explorer 助理解代码生成
  • 持续关注社区和标准发展,保持知识更新

本教程完