现代 C++
「现代 C++」通常指 C++11 之后的演进,核心目标是用更安全、更表达力强的写法替代裸指针与手写循环。掌握以下特性是高效使用新标准库的前提。
类型推导与控制流
auto 让编译器推断类型,适合复杂类型与迭代器。decltype(expr) 取出表达式的类型,常与尾置返回类型配合。
auto v = std::vector<int>{1, 2, 3};
for (const auto& x : v) { /* 范围 for */ }
if constexpr 在编译期分支,常用于模板代码。C++17 的结构化绑定让 auto [a, b] = pair; 一次解构多个值。
lambda 表达式
lambda 是一种匿名函数对象,可捕获上下文变量。[] 不捕获,[&] 按引用捕获,[=] 按值捕获,C++14 起支持初始化捕获([x = 1]),C++17 起 [*this] 捕获当前对象。
auto square = [](int x) { return x * x; };
std::vector<int> v = {1, 2, 3};
std::transform(v.begin(), v.end(), v.begin(), square);
智能指针
std::unique_ptr<T> 独占所有权,零开销。std::shared_ptr<T> 共享所有权,内部有引用计数。std::weak_ptr<T> 不增加计数,用于打破循环引用。优先使用 std::make_unique / std::make_shared。
auto p = std::make_unique<std::vector<int>>(10, 0);
p->push_back(42);
move 语义与右值引用
右值引用(T&&)绑定到即将销毁的对象,允许「偷」其资源。std::move 把左值强制转为右值,触发移动构造或移动赋值。容器扩容、函数返回值优化都依赖此机制。
std::string a = "hello";
std::string b = std::move(a); // a 变为空
工具类型与概念
std::optional<T>:表达「可能没有值」。std::variant<Ts...>:类型安全的联合体。std::any:可保存任意可拷贝类型。std::span<T>(C++20):非拥有的视图。concept与requires(C++20):约束模板参数能力,显著提升错误信息可读性。