Effective Modern C++ 学习地图

严格对齐原书八章与 42 个 Items:从类型推导、现代对象规则、智能指针和移动转发,走到 Lambda、并发 API 与两项成本微调。

学习目标

  • 能说出原书八章、42 个 Items 的准确范围、核心问题和前后依赖
  • 能设计“推导→对象规则→ownership→value category→closure→concurrency→成本”的学习路线
  • 能使用预测、最小复现、负例和真实迁移证据验收每个 Item,而不是只背结论

从“42 条不是四个模糊板块”开始

Effective Modern C++ 面向 C++11/14 带来的类型推导、对象语义、ownership、move/forward、lambda 与 concurrency 变化。原书按八章组织 42 个 Items,每章解决一组连续问题;把它压缩成四块会丢掉 Moving to Modern C++、Lambda 和 Tweaks 的真实边界。

先预测每章依赖上一章的哪种能力,再沿图检查是否能解释全部 Items。

八章顺序从“看清类型”递进到 ownership、value category、callable 与 concurrency,最后用两项成本微调收束。

第一章 Items 1-4:Deducing Types

template type deduction、auto 与 decltype 看似相似,却对 references、cv、arrays/functions 和 initializer lists 有不同规则;Item 4 再教你用 IDE、compiler diagnostics 与 type tools 观察结果。

这一章的验收不是“会写 auto”,而是能在编译前推导 T、parameter 和 expression type,并解释 decltype(name)decltype((name)) 的差异。

int value = 0;
static_assert(std::is_same_v<decltype(value), int>);
static_assert(std::is_same_v<decltype((value)), int&>);

第二章 Items 5-6:auto

Item 5 说明 auto 减少冗长、避免未初始化并跟随表达式真实类型;Item 6 处理 vector<bool> proxy 等 invisible proxy class,必要时用 explicitly typed initializer 固化目标语义。

第三章 Items 7-17:Moving to Modern C++

这一章不是零散语法:braces/nullptr/alias/scoped enum/deleted function/override/const iterator/noexcept/constexpr/thread-safe const 与 special-member generation 共同建立可预测对象规则。

重点是边界:braces 防 narrowing 却偏向 initializer_list;noexcept 会影响 container move;user-declared destructor 可能抑制 move generation;logical const 在并发下仍需同步 mutable state。

第四章 Items 18-22:Smart Pointers

unique_ptr 表达 exclusive ownership,shared_ptr 用 control block 表达 shared ownership,weak_ptr 观察但不延寿;make functions 缩短异常窗口,Pimpl 则要求在 complete type 可见处正确生成/destruct special members。

验收点包括 deleter type、control-block duplication、cycles、weak expiration race、make 的优缺点和 incomplete type destruction。

auto owner = std::make_shared<Resource>();
std::weak_ptr<Resource> observer = owner;
owner.reset();
assert(observer.expired());

第五章 Items 23-30:Rvalue References、Move 与 Forwarding

std::move 是无条件 cast,std::forward 是有条件 cast;forwarding reference 依靠特殊 deduction 与 reference collapsing。unconstrained forwarding overload 会贪婪劫持 copy/index/derived calls,Item 27 用不同名称、const-reference/value、tag dispatch 和 constraints 修复。

Items 29-30 再限制性能想象与适用输入:move 可能不存在、不便宜或未被采用;braced lists、overload sets、static const members 和 bitfields 可能无法完美转发。

后续章节反复使用前置模型;跳过推导、ownership 或 value category,会把并发与 lambda 问题误诊成语法问题。

第六章 Items 31-34:Lambda Expressions

避免默认 capture,原因不只是风格:[&] 隐藏 dangling references,[=] 可能只复制 this pointer,global/static state 根本不 capture。init capture 把 move-only ownership 放进 closure;generic lambda 用 std::forward<decltype(param)> 保留 category;普通调用优先 lambda 而非 bind。

第七章 Items 35-40:The Concurrency API

优先 task/outcome 而非裸 thread identity;必须异步时指定 launch::async;所有 thread paths 最终 unjoinable;future destructor 行为取决于 shared-state 来源、policy 与最后引用;void future 可做 one-shot event;atomic 与 volatile 解决不同问题。

并发章节要画 timeline 和 happens-before,不能只运行一次“看起来成功”。重点验证 deferred、异常路径、destructor waits、broken promise、data races 与 memory ordering。

std::atomic<bool> ready{false};
Data data;
// producer: prepare data, then release-store ready
// consumer: acquire-load ready, then inspect data

第八章 Items 41-42:Tweaks

按值传参只在 copyable、move cheap、always copied 时考虑,还要排除 assignment allocation 与 slicing;emplace 只在 constructor arguments 尚未形成 value_type 且 insertion 大概率成功时可能消除 temporary,并要检查 explicit constructors 与 ownership window。

这两项收尾强调全书方法:现代语法不是无条件替换旧写法,任何“更快”都要有适用条件和反例。

两条学习路线

系统路线:Items 1-6 类型 → 7-17 对象规则 → 18-22 ownership → 23-30 value category → 31-34 closures → 35-40 concurrency → 41-42 costs。

问题路线:类型误判读 1-6;special-member/初始化 bug 读 7-17;泄漏/cycle 读 18-22;move/overload bug 读 23-30;async lifetime 读 31-40。修复后回到系统路线补前置。

每个 Item 的证据链

能复述条款不算掌握;必须留下类型、诊断、调用路径、负例和真实迁移证据。

只复述“prefer X”不算掌握。必须能写出何时不适用、哪个 overload 被选、对象何时销毁、哪条 memory relation 成立,以及修复后哪项测试改变。

小结

  • 原书由八章 42 Items 构成,学习地图必须保持每章与每条边界
  • 推导和对象规则是 ownership/value-category 的前置,closure 又是 concurrency task 的载体
  • Smart Pointers、Move/Forwarding、Lambda 与 Concurrency 都以 lifetime/ownership 证据为核心
  • Items 41-42 是条件化优化,不应覆盖语义与安全规则
  • 系统路线建立完整模型;问题路线解决故障后必须回补前置
  • 每个 Item 用预测、复现、解释、修复、反证和迁移验收

资料与写作方式声明

本章以Effective Modern C++, Items 1-42权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

名词解释

本章出现的专业名词,用大白话再讲一遍。

八章四十二项路线

原书八章与 42 Items 的官方结构。

模板类型推导

template pattern 与 argument 决定 T。

显式类型初始化器

以目标类型约束 auto initializer。

现代声明契约

把初始化继承和特殊成员意图写入声明。

智能指针 ownership contract

拥有释放观察和转移协议。

forwarding reference

通过 deduction/collapse 保存 category。

closure object

持有 capture state 的 callable object。

task outcome channel

future shared state 的结果错误通道。

条件化成本优化

有适用条件和实测证据的局部优化。

问题驱动回补路线

故障切入后补齐前置的路线。

Item 证据链
证明掌握条款的六类证据。

练习

  1. 问题 1:旧模块同时有 shared_ptr cycle、forwarding overload 劫持和 async dangling capture。 设计学习与修复顺序。
  1. 问题 2:学习者能背“用 atomic 不用 volatile”。 还缺哪些掌握证据?
  1. 问题 3:制定四周路线,每周必须有真实迁移产出。

讨论

评论区加载中…