C++ lambda
以下是 Markdown 格式的 C++11 技术博客:
1 | # C++11:现代 C++ 的里程碑式变革 |
最佳实践:
- 使用
auto避免类型不匹配问题。例如,在范围 for 循环中,std::pair<const std::string, int>与std::pair<std::string, int>的细微差别可能导致不必要的拷贝 - 始终初始化
auto变量,否则编译器无法推导类型
1 | auto x = 0; // ✓ 正确:int |
1.2 列表初始化(Uniform Initialization)
C++11 统一了初始化语法,使用花括号 {} 进行初始化:
1 | std::vector<int> vec{1, 2, 3}; |
花括号初始化还能避免”最棘手的解析”(Most Vexing Parse)问题:
1 | Widget w1(10); // 调用构造函数,传入参数 10 |
二、Lambda 表达式:匿名函数的优雅
Lambda 表达式是 C++11 最激动人心的特性之一,它允许在代码中内联定义匿名函数。
2.1 基本语法
1 | [capture](parameters) -> return_type { body } |
示例:
1 | std::vector<int> nums{1, 2, 3, 4, 5}; |
2.2 捕获方式
| 捕获方式 | 含义 |
|---|---|
[] |
不捕获任何外部变量 |
[=] |
以值捕获所有外部变量 |
[&] |
以引用捕获所有外部变量 |
[this] |
捕获当前对象的指针 |
[=, &x] |
默认以值捕获,但 x 以引用捕获 |
2.3 存储 Lambda
使用 auto 存储 lambda 比 std::function 更高效:
1 | // 推荐:使用 auto,无额外开销 |
auto 定义的 lambda 调用速度更快,且不会抛出 bad_alloc 异常。
三、智能指针:内存管理的革命
C++11 废弃了有缺陷的 std::auto_ptr,引入了三款强大的智能指针,彻底改变了 C++ 的内存管理方式。
3.1 std::unique_ptr:独占所有权
unique_ptr 是轻量级的智能指针,大小与原始指针相同,保证独占所有权。
1 |
|
关键特性:
- 不可复制,只可移动(Move-only)
- 零开销抽象:无额外内存占用(针对无状态删除器)
- 支持数组特化:
std::unique_ptr<int[]>
3.2 std::shared_ptr:共享所有权
shared_ptr 使用引用计数管理资源,当最后一个引用消失时自动释放。
1 | void sharedPtrDemo() { |
注意:shared_ptr 需要额外的控制块(control block),内存开销比 unique_ptr 大。
3.3 std::weak_ptr:弱引用
weak_ptr 用于打破 shared_ptr 的循环引用问题:
1 | class Node { |
3.4 智能指针使用准则
- 默认使用
unique_ptr:除非需要共享所有权,否则优先使用unique_ptr - 使用
make_shared和make_unique:避免显式new,减少内存泄漏风险 - 避免
shared_ptr的循环引用:使用weak_ptr打破循环 - 不要混用智能指针和原始指针:不要将同一个原始指针交给多个智能指针管理
四、右值引用与移动语义
4.1 左值与右值
- 左值(Lvalue):有名称、有持久地址的对象(如变量)
- 右值(Rvalue):临时对象、字面量、即将销毁的值
4.2 右值引用
C++11 引入 && 表示右值引用,允许”窃取”临时对象的资源:
1 | std::vector<int> createVector() { |
4.3 完美转发(Perfect Forwarding)
使用 std::forward 在模板中保持参数的值类别:
1 | template<typename T, typename... Args> |
注意:std::move 无条件转为右值,std::forward 根据模板参数决定是否保持原值类别。
五、并发支持:标准线程库
C++11 首次在标准库中提供了跨平台的线程支持:
1 |
|
关键组件:
std::thread:线程管理std::mutex/std::lock_guard/std::unique_lock:互斥锁std::condition_variable:条件变量std::future/std::promise:异步结果传递std::async:异步任务
六、其他重要特性
6.1 nullptr:类型安全的空指针
1 | void foo(int x) { std::cout << "int\n"; } |
6.2 constexpr:编译期计算
1 | constexpr int square(int x) { return x * x; } |
6.3 范围 for 循环
1 | std::vector<int> nums{1, 2, 3, 4, 5}; |
6.4 强类型枚举(Scoped Enums)
1 | enum class Color { Red, Green, Blue }; // 不会污染命名空间 |
七、总结与最佳实践
C++11 的引入标志着 C++ 进入现代编程语言行列。以下是核心要点:
| 特性 | 使用建议 |
|---|---|
auto |
优先使用,特别是在迭代器和 lambda 中 |
| 智能指针 | 默认 unique_ptr,需要共享时用 shared_ptr,注意循环引用 |
| Lambda | 捕获尽量明确,避免默认捕获大型对象 |
| 移动语义 | 为自定义类实现移动构造函数和移动赋值运算符 |
| 并发 | 优先使用标准库线程,而非平台特定 API |
编译器支持:GCC 4.8+、Clang 3.3+、MSVC 2013+ 均完整支持 C++11。
掌握 C++11 不仅是学习新语法,更是思维方式的转变——从手动管理资源到利用 RAII 自动管理,从繁琐的类型声明到让编译器推导,从危险的原始指针到安全的智能指针。这些改变让 C++ 代码更简洁、更安全、更高效。
参考资源:
- 《Effective Modern C++》by Scott Meyers
- cppreference.com
- C++ Core Guidelines

