c++特性
以下按常用频次排序。每个特性给出最精简的语法和示例。
Lambda 表达式
// [捕获](参数) -> 返回类型 { 函数体 }
auto add = [](int a, int b) -> int { return a + b; };
auto f = [&x, y](int z) { x += y + z; }; // x引用捕获, y值捕获
// 捕获简写
[=] { /* 全部值捕获 */ }
[&] { /* 全部引用捕获 */ }
[=, &x] { /* x引用,其余值捕获 */ }
auto 关键字
auto i = 42; // int
auto s = string{"hi"}; // string
auto it = v.begin(); // vector<int>::iterator
// 结合引用/const
const auto& ref = vec; // const 引用
空指针 nullptr
int* p = nullptr; // 替代 NULL,类型安全
// 函数重载时:f(nullptr) 走 f(int*),f(NULL) 可能走错
基于范围的 for 循环
for (auto& x : vec) { x *= 2; } // 修改用引用
for (const auto& x : vec) { cout << x; } // 只读用 const 引用
{} 统一初始化
int a{5};
vector<int> v{1, 2, 3};
struct P { int x, y; };
P p{1, 2}; // 聚合初始化
成员变量默认初始值
class A {
int x = 0; // 直接给默认值
string s{"hi"};
};
右值引用和 move 语义
// 左值:可取地址的;右值:字面量、临时对象、表达式结果
int a = 5;
int& lref = a; // 左值引用
int&& rref = 5; // 右值引用
// move:将左值转为右值引用,触发移动语义
vector<int> v2 = move(v1); // v1 内容被移走,v1 变为空
// 移动构造函数(浅拷贝指针,移交所有权)
class Buffer {
char* data;
public:
Buffer(Buffer&& other) noexcept
: data(other.data) { other.data = nullptr; }
};
unique_ptr(独占智能指针)
#include <memory>
auto p = make_unique<int>(42); // 推荐写法
auto p2 = move(p); // 转移所有权,p 变 nullptr
// 离开作用域自动 delete,不可拷贝,不可容器传参(可 move)
shared_ptr(共享智能指针)
#include <memory>
auto sp = make_shared<int>(42); // 推荐写法
auto sp2 = sp; // 引用计数
// 计数归零自动 delete。注意循环引用导致泄漏。
make_unique/make_shared比new更安全(无裸 new,异常安全)。
decltype 关键字
int x = 0;
decltype(x) y = 1; // y 类型为 int
decltype((x)) z = x; // 双括号→int&
// 主要用于泛型中推导返回类型
万能引用与 forward 转发
// T&& 在模板中为万能引用,可接受左/右值
template<typename T>
void wrapper(T&& arg) {
foo(forward<T>(arg)); // 保持原值类别转发
}
C++14 补充
| 特性 | 示例 |
|---|---|
| 二进制常量 | int b = 0b1010; |
| 返回类型自动推导 | auto f() { return 42; } |
| 泛型 lambda | auto f = [](auto x) { return x * 2; }; |
| make_unique | C++14 引入,用法见上 |
C++17 补充
| 特性 | 示例 |
|---|---|
| 结构化绑定 | auto [x, y] = make_pair(1, 2); |
| if 初始化 | if (auto it = m.find(k); it != m.end()) { ... } |
| CTAD | vector v{1, 2, 3}; 自动推导为 vector<int> |
std::optional |
可能无值的返回值,if (opt.has_value()) |