目录
- 第一部分:基础语法
- 第一章:基本类型与变量
- 第二章:运算符
- 第三章:控制流
- 第四章:函数
- 第二部分:复合类型
- 第五章:数组与字符串
- 第六章:指针与引用
- 第七章:结构体与联合体
- 第八章:枚举
- 第三部分:面向对象编程
- 第九章:类与对象
- 第十章:继承
- 第十一章:多态
- 第十二章:抽象类与接口
- 第四部分:模板与泛型
- 第十三章:函数模板
- 第十四章:类模板
- 第十五章:模板特化与偏特化
- 第十六章:可变参数模板
- 第五部分:STL 标准库
- 第十七章:容器
- 第十八章:迭代器
- 第十九章:算法
- 第二十章:函数对象与 Lambda
- 第六部分:内存管理
- 第二十一章:栈与堆
- 第二十二章:智能指针
- 第二十三章:移动语义
- 第七部分:异常处理
- 第八部分:并发编程
- 第二十五章:线程
- 第二十六章:互斥锁与原子操作
- 第二十七章:条件变量与异步
- 第九部分:现代 C++ 特性
- 第二十八章:C++11 新特性
- 第二十九章:C++14 新特性
- 第三十章:C++17 新特性
- 第三十一章:C++20 新特性
- 第三十二章:C++23 新特性
- 第十部分:预处理与编译
- 第十一部分:文件与流
第一部分:基础语法
第一章:基本类型与变量
1.1 基本数据类型
| 类型 |
关键字 |
大小(字节) |
范围 |
| 布尔型 |
bool |
1 |
true / false |
| 字符型 |
char |
1 |
-128 ~ 127 |
| 宽字符 |
wchar_t |
2 或 4 |
平台相关 |
| 短整型 |
short |
2 |
-32768 ~ 32767 |
| 整型 |
int |
4 |
-2^31 ~ 2^31-1 |
| 长整型 |
long |
4 或 8 |
平台相关 |
| 长长整型 |
long long |
8 |
-2^63 ~ 2^63-1 |
| 单精度浮点 |
float |
4 |
±3.4e38 |
| 双精度浮点 |
double |
8 |
±1.7e308 |
| 长双精度 |
long double |
8/12/16 |
平台相关 |
| 空类型 |
void |
0 |
无 |
1.2 修饰符
signed // 有符号(默认)
unsigned // 无符号
short // 短
long // 长
const // 常量
volatile // 易变
static // 静态
extern // 外部
mutable // 可变(用于 const 成员函数中修改成员)
1.3 变量声明与定义
int a; // 声明
int b = 10; // 初始化(C 风格)
int c(10); // 直接初始化
int d{10}; // 列表初始化(C++11)
int e = {10}; // 拷贝列表初始化
// 多变量声明
int x, y, z;
int x = 1, y = 2, z = 3;
// auto 类型推导(C++11)
auto i = 42; // int
auto d = 3.14; // double
auto s = "hello"; // const char*
// decltype(C++11)
decltype(x) w; // w 的类型与 x 相同
1.4 常量
const int MAX = 100; // const 常量
constexpr int SIZE = 256; // 编译期常量(C++11)
#define PI 3.14159 // 宏定义
// const 指针
const int* p1; // 指向常量的指针(不能通过 p1 修改值)
int* const p2; // 常量指针(不能修改 p2 的指向)
const int* const p3; // 指向常量的常量指针
// const 引用
const int& ref = a; // 常量引用
1.5 类型转换
// C 风格转换
int a = (int)3.14;
// C++ 风格转换
static_cast<int>(3.14); // 静态转换(编译期)
dynamic_cast<Base*>(derived); // 动态转换(运行时,用于多态)
const_cast<int*>(const_ptr); // 去除 const
reinterpret_cast<int*>(ptr); // 重新解释(危险)
第二章:运算符
2.1 算术运算符
+ // 加
- // 减
* // 乘
/ // 除
% // 取模
++ // 自增
-- // 自减
2.2 关系运算符
== // 等于
!= // 不等于
< // 小于
> // 大于
<= // 小于等于
>= // 大于等于
2.3 逻辑运算符
&& // 逻辑与
|| // 逻辑或
! // 逻辑非
2.4 位运算符
& // 按位与
| // 按位或
^ // 按位异或
~ // 按位取反
<< // 左移
>> // 右移
2.5 赋值运算符
= // 赋值
+= // 加等
-= // 减等
*= // 乘等
/= // 除等
%= // 模等
&= // 按位与等
|= // 按位或等
^= // 按位异或等
<<= // 左移等
>>= // 右移等
2.6 其他运算符
?: // 三元条件
, // 逗号
sizeof // 大小
& // 取地址
* // 解引用
-> // 成员访问(指针)
. // 成员访问(对象)
:: // 作用域
new // 动态分配
delete // 动态释放
第三章:控制流
3.1 条件语句
// if-else
if (condition) {
// ...
} else if (condition2) {
// ...
} else {
// ...
}
// 三元运算符
int max = (a > b) ? a : b;
// switch
switch (value) {
case 1:
// ...
break;
case 2:
// ...
break;
default:
// ...
break;
}
// if constexpr(C++17)
if constexpr (sizeof(T) == 4) {
// 编译期条件
}
3.2 循环语句
// for 循环
for (int i = 0; i < 10; i++) {
// ...
}
// 范围 for(C++11)
for (const auto& item : container) {
// ...
}
// while 循环
while (condition) {
// ...
}
// do-while 循环
do {
// ...
} while (condition);
// break 和 continue
for (int i = 0; i < 10; i++) {
if (i == 5) break; // 跳出循环
if (i == 3) continue; // 跳过本次迭代
}
3.3 跳转语句
break; // 跳出循环或 switch
continue; // 跳过本次循环迭代
return; // 返回
goto label; // 跳转到标签(不推荐使用)
第四章:函数
4.1 函数定义
// 基本函数
int add(int a, int b) {
return a + b;
}
// 无返回值
void print(const std::string& msg) {
std::cout << msg << std::endl;
}
// 默认参数
void greet(const std::string& name = "World") {
std::cout << "Hello, " << name << std::endl;
}
// 函数声明(原型)
int add(int a, int b);
4.2 函数重载
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int add(int a, int b, int c) { return a + b + c; }
4.3 内联函数
inline int square(int x) {
return x * x;
}
4.4 constexpr 函数(C++11)
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int f5 = factorial(5); // 编译期计算
4.5 函数指针
int add(int a, int b) { return a + b; }
// 函数指针
int (*func_ptr)(int, int) = add;
int result = func_ptr(3, 4);
// using 别名
using MathFunc = int(*)(int, int);
MathFunc f = add;
4.6 Lambda 表达式(C++11)
// 基本 lambda
auto greet = []() { std::cout << "Hello" << std::endl; };
greet();
// 带参数
auto add = [](int a, int b) { return a + b; };
int sum = add(3, 4);
// 带捕获
int x = 10;
auto f1 = [x]() { return x; }; // 值捕获
auto f2 = [&x]() { x++; }; // 引用捕获
auto f3 = [=]() { return x; }; // 捕获所有外部变量(值)
auto f4 = [&]() { x++; }; // 捕获所有外部变量(引用)
auto f5 = [x]() mutable { x++; }; // 可修改值捕获
// 泛型 lambda(C++14)
auto generic = [](auto a, auto b) { return a + b; };
第二部分:复合类型
第五章:数组与字符串
5.1 数组
// C 风格数组
int arr[5] = {1, 2, 3, 4, 5};
int arr2[] = {1, 2, 3}; // 自动推导大小
int arr3[5] = {}; // 全部初始化为 0
// std::array(C++11)
#include <array>
std::array<int, 5> arr4 = {1, 2, 3, 4, 5};
arr4.size(); // 获取大小
arr4.at(0); // 带边界检查的访问
arr4[0]; // 不带边界检查的访问
// 多维数组
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
5.2 字符串
// C 风格字符串
char str1[] = "Hello";
char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};
const char* str3 = "Hello";
// std::string
#include <string>
std::string s1 = "Hello";
std::string s2("World");
std::string s3(5, 'A'); // "AAAAA"
// 常用操作
s1.length(); // 长度
s1.size(); // 大小(同 length)
s1.empty(); // 是否为空
s1[0]; // 访问字符
s1.at(0); // 带边界检查的访问
s1 + s2; // 拼接
s1.append(s2); // 追加
s1.substr(0, 3); // 子串
s1.find("ll"); // 查找
s1.replace(0, 3, "Hi"); // 替换
s1.compare(s2); // 比较
s1.c_str(); // 转为 C 字符串
// 字符串与数字转换
int i = std::stoi("42");
double d = std::stod("3.14");
std::string s = std::to_string(42);
第六章:指针与引用
6.1 指针
int a = 10;
int* p = &a; // p 指向 a
int b = *p; // 解引用,b = 10
// 空指针
int* p1 = nullptr; // C++11 推荐
int* p2 = NULL; // C 风格
int* p3 = 0; // 不推荐
// 指针运算
int arr[] = {1, 2, 3, 4, 5};
int* p = arr; // p 指向 arr[0]
p++; // p 指向 arr[1]
p += 2; // p 指向 arr[3]
// void 指针
void* vp = &a; // 可以指向任何类型
int* ip = static_cast<int*>(vp); // 需要转换
// 指向指针的指针
int a = 10;
int* p = &a;
int** pp = &p; // 二级指针
6.2 引用
int a = 10;
int& ref = a; // ref 是 a 的别名
ref = 20; // a 变为 20
// const 引用
const int& cref = a; // 不能通过 cref 修改 a
// 引用必须初始化
// int& ref2; // 错误!
// 引用不能重新绑定
int b = 30;
ref = b; // 这是赋值,不是重新绑定!a 变为 30
// 右值引用(C++11)
int&& rref = 10; // 绑定到右值
int&& rref2 = std::move(a); // 将 a 转为右值引用
6.3 指针 vs 引用
| 特性 |
指针 |
引用 |
| 是否可为空 |
可以(nullptr) |
不可以 |
| 是否可重新绑定 |
可以 |
不可以 |
| 是否需要初始化 |
不需要 |
必须初始化 |
| 语法 |
*p |
ref(直接使用) |
| 算术运算 |
支持 |
不支持 |
第七章:结构体与联合体
7.1 结构体
struct Point {
double x;
double y;
// 成员函数
double distanceTo(const Point& other) const {
double dx = x - other.x;
double dy = y - other.y;
return std::sqrt(dx * dx + dy * dy);
}
// 构造函数
Point() : x(0), y(0) {}
Point(double x, double y) : x(x), y(y) {}
};
// 使用
Point p1;
Point p2(3.0, 4.0);
Point p3 = {5.0, 6.0}; // 聚合初始化
double d = p2.distanceTo(p3);
7.2 联合体
union Data {
int i;
float f;
char c;
};
Data d;
d.i = 42; // 存储 int
d.f = 3.14f; // 覆盖 int,存储 float(同时只有一个成员有效)
7.3 匿名结构体/联合体
struct {
int x;
int y;
} point;
point.x = 10;
point.y = 20;
第八章:枚举
8.1 传统枚举
enum Color {
RED, // 0
GREEN, // 1
BLUE // 2
};
enum Color2 {
RED = 1,
GREEN = 5,
BLUE = 10
};
8.2 枚举类(C++11)
enum class Color {
RED,
GREEN,
BLUE
};
Color c = Color::RED; // 必须使用作用域
// 不能隐式转换为 int
// int i = Color::RED; // 错误!
int i = static_cast<int>(Color::RED); // 正确
// 指定底层类型
enum class Direction : uint8_t {
UP = 0,
DOWN = 1,
LEFT = 2,
RIGHT = 3
};
第三部分:面向对象编程
第九章:类与对象
9.1 类的定义
class Person {
private:
std::string name_;
int age_;
public:
// 构造函数
Person() : name_("Unknown"), age_(0) {}
Person(const std::string& name, int age) : name_(name), age_(age) {}
// 拷贝构造函数
Person(const Person& other) : name_(other.name_), age_(other.age_) {}
// 移动构造函数(C++11)
Person(Person&& other) noexcept
: name_(std::move(other.name_)), age_(other.age_) {}
// 析构函数
~Person() {}
// 拷贝赋值运算符
Person& operator=(const Person& other) {
if (this != &other) {
name_ = other.name_;
age_ = other.age_;
}
return *this;
}
// 移动赋值运算符(C++11)
Person& operator=(Person&& other) noexcept {
if (this != &other) {
name_ = std::move(other.name_);
age_ = other.age_;
}
return *this;
}
// 成员函数
const std::string& getName() const { return name_; }
int getAge() const { return age_; }
void setName(const std::string& name) { name_ = name; }
void setAge(int age) { age_ = age; }
// 静态成员
static int count;
static int getCount() { return count; }
// 友元
friend std::ostream& operator<<(std::ostream& os, const Person& p);
};
// 静态成员初始化
int Person::count = 0;
// 友元函数实现
std::ostream& operator<<(std::ostream& os, const Person& p) {
os << "Person(" << p.name_ << ", " << p.age_ << ")";
return os;
}
9.2 访问控制
class MyClass {
public: // 公有:任何地方都可以访问
int a;
protected: // 保护:类内部和子类可以访问
int b;
private: // 私有:只有类内部可以访问
int c;
};
9.3 特殊成员函数
| 函数 |
签名 |
何时调用 |
| 默认构造 |
ClassName() |
创建对象时 |
| 拷贝构造 |
ClassName(const ClassName&) |
拷贝对象时 |
| 移动构造 |
ClassName(ClassName&&) |
移动对象时 |
| 拷贝赋值 |
operator=(const ClassName&) |
拷贝赋值时 |
| 移动赋值 |
operator=(ClassName&&) |
移动赋值时 |
| 析构函数 |
~ClassName() |
对象销毁时 |
9.4 运算符重载
class Vector2D {
public:
double x, y;
Vector2D(double x = 0, double y = 0) : x(x), y(y) {}
// 算术运算符
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
Vector2D operator-(const Vector2D& other) const {
return Vector2D(x - other.x, y - other.y);
}
Vector2D operator*(double scalar) const {
return Vector2D(x * scalar, y * scalar);
}
// 比较运算符
bool operator==(const Vector2D& other) const {
return x == other.x && y == other.y;
}
bool operator!=(const Vector2D& other) const {
return !(*this == other);
}
// 下标运算符
double& operator[](int index) {
return (index == 0) ? x : y;
}
// 函数调用运算符
double operator()() const {
return std::sqrt(x * x + y * y);
}
// 类型转换运算符
operator bool() const {
return x != 0 || y != 0;
}
// 流输出运算符(友元)
friend std::ostream& operator<<(std::ostream& os, const Vector2D& v) {
os << "(" << v.x << ", " << v.y << ")";
return os;
}
};
// 非成员运算符
Vector2D operator*(double scalar, const Vector2D& v) {
return v * scalar;
}
9.5 this 指针
class Box {
int value;
public:
Box& setValue(int value) {
this->value = value; // 区分成员变量和参数
return *this; // 返回自身引用(链式调用)
}
};
Box b;
b.setValue(1).setValue(2); // 链式调用
第十章:继承
10.1 基本继承
class Animal {
protected:
std::string name_;
public:
Animal(const std::string& name) : name_(name) {}
virtual ~Animal() = default; // 虚析构函数
virtual void speak() const {
std::cout << "..." << std::endl;
}
const std::string& getName() const { return name_; }
};
class Dog : public Animal {
public:
Dog(const std::string& name) : Animal(name) {}
void speak() const override {
std::cout << name_ << " says: Woof!" << std::endl;
}
};
class Cat : public Animal {
public:
Cat(const std::string& name) : Animal(name) {}
void speak() const override {
std::cout << name_ << " says: Meow!" << std::endl;
}
};
10.2 继承方式
class Derived : public Base {}; // 公有继承
class Derived : protected Base {}; // 保护继承
class Derived : private Base {}; // 私有继承
| 继承方式 |
基类 public |
基类 protected |
基类 private |
| public |
public |
protected |
不可访问 |
| protected |
protected |
protected |
不可访问 |
| private |
private |
private |
不可访问 |
10.3 多重继承
class Flyable {
public:
virtual void fly() = 0;
};
class Swimmable {
public:
virtual void swim() = 0;
};
class Duck : public Flyable, public Swimmable {
public:
void fly() override { std::cout << "Flying" << std::endl; }
void swim() override { std::cout << "Swimming" << std::endl; }
};
10.4 虚继承(解决菱形继承)
class Animal {
public:
int age;
};
// 虚继承:避免菱形继承中的二义性
class Mammal : virtual public Animal {};
class Bird : virtual public Animal {};
class Bat : public Mammal, public Bird {
// 只有一份 Animal 的 age
};
第十一章:多态
11.1 虚函数
class Shape {
public:
virtual double area() const = 0; // 纯虚函数
virtual void draw() const { // 虚函数
std::cout << "Drawing shape" << std::endl;
}
virtual ~Shape() = default; // 虚析构函数
};
class Circle : public Shape {
double radius_;
public:
Circle(double r) : radius_(r) {}
double area() const override {
return 3.14159 * radius_ * radius_;
}
void draw() const override {
std::cout << "Drawing circle" << std::endl;
}
};
11.2 虚函数表(vtable)
┌─────────────┐
│ Shape │
│ ┌─────────┐ │
│ │ vptr │──────→ ┌──────────────┐
│ ├─────────┤ │ │ vtable │
│ │ 成员 │ │ │ ┌──────────┐ │
│ └─────────┘ │ │ │ area() │ │
└─────────────┘ │ │ draw() │ │
│ │ ~Shape() │ │
│ └──────────┘ │
└──────────────┘
11.3 override 和 final(C++11)
class Base {
public:
virtual void foo() const = 0;
};
class Derived : public Base {
public:
void foo() const override { // 显式标记重写
// ...
}
};
class Final final : public Base { // 不能被继承
public:
void foo() const final { // 不能被重写
// ...
}
};
第十二章:抽象类与接口
12.1 抽象类
class AbstractShape {
public:
virtual double area() const = 0; // 纯虚函数
virtual double perimeter() const = 0; // 纯虚函数
virtual ~AbstractShape() = default;
// 可以有非虚函数
void print() const {
std::cout << "Area: " << area() << std::endl;
}
};
// AbstractShape a; // 错误!不能实例化抽象类
12.2 接口(纯抽象类)
class IDrawable {
public:
virtual void draw() const = 0;
virtual void resize(double factor) = 0;
virtual ~IDrawable() = default;
};
class IPrintable {
public:
virtual void print(std::ostream& os) const = 0;
virtual ~IPrintable() = default;
};
class Widget : public IDrawable, public IPrintable {
public:
void draw() const override { /* ... */ }
void resize(double factor) override { /* ... */ }
void print(std::ostream& os) const override { /* ... */ }
};
第四部分:模板与泛型
第十三章:函数模板
13.1 基本函数模板
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 使用
int i = max(3, 4); // T = int
double d = max(3.14, 2.7); // T = double
13.2 多类型参数
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
// C++14 简化
template <typename T, typename U>
auto add(T a, U b) {
return a + b;
}
13.3 非类型模板参数
template <int N>
int factorial() {
int result = 1;
for (int i = 2; i <= N; i++) {
result *= i;
}
return result;
}
int f5 = factorial<5>(); // 编译期计算 5! = 120
13.4 模板默认参数
template <typename T = int, int Size = 10>
class Array {
T data[Size];
// ...
};
Array<> a; // Array<int, 10>
Array<double> b; // Array<double, 10>
Array<double, 20> c; // Array<double, 20>
第十四章:类模板
14.1 基本类模板
template <typename T>
class Stack {
private:
std::vector<T> data_;
public:
void push(const T& item) {
data_.push_back(item);
}
void pop() {
if (data_.empty()) throw std::runtime_error("Stack is empty");
data_.pop_back();
}
T& top() {
if (data_.empty()) throw std::runtime_error("Stack is empty");
return data_.back();
}
const T& top() const {
if (data_.empty()) throw std::runtime_error("Stack is empty");
return data_.back();
}
bool empty() const { return data_.empty(); }
size_t size() const { return data_.size(); }
};
// 使用
Stack<int> intStack;
intStack.push(42);
intStack.push(10);
Stack<std::string> strStack;
strStack.push("Hello");
14.2 成员函数模板
class Printer {
public:
template <typename T>
void print(const T& value) {
std::cout << value << std::endl;
}
};
Printer p;
p.print(42);
p.print("Hello");
p.print(3.14);
第十五章:模板特化与偏特化
15.1 完全特化
template <typename T>
class Printer {
public:
void print(const T& value) {
std::cout << "Generic: " << value << std::endl;
}
};
// 完全特化:针对 const char*
template <>
class Printer<const char*> {
public:
void print(const char* value) {
std::cout << "String: " << value << std::endl;
}
};
// 完全特化:针对 bool
template <>
class Printer<bool> {
public:
void print(bool value) {
std::cout << "Boolean: " << (value ? "true" : "false") << std::endl;
}
};
15.2 偏特化
// 通用版本
template <typename T1, typename T2>
class Pair {
T1 first_;
T2 second_;
public:
Pair(const T1& f, const T2& s) : first_(f), second_(s) {}
void print() const {
std::cout << first_ << ", " << second_ << std::endl;
}
};
// 偏特化:两个类型相同
template <typename T>
class Pair<T, T> {
T first_;
T second_;
public:
Pair(const T& f, const T& s) : first_(f), second_(s) {}
void print() const {
std::cout << "Same type: " << first_ << ", " << second_ << std::endl;
}
};
// 偏特化:指针类型
template <typename T1, typename T2>
class Pair<T1*, T2*> {
T1* first_;
T2* second_;
public:
Pair(T1* f, T2* s) : first_(f), second_(s) {}
void print() const {
std::cout << "Pointers: " << *first_ << ", " << *second_ << std::endl;
}
};
第十六章:可变参数模板
16.1 可变参数函数模板
// 递归终止
void print() {
std::cout << std::endl;
}
// 可变参数版本
template <typename T, typename... Args>
void print(const T& first, const Args&... args) {
std::cout << first << " ";
print(args...);
}
// 使用
print(1, 2.5, "hello", 'c'); // 输出: 1 2.5 hello c
16.2 sizeof... 运算符
template <typename... Args>
constexpr size_t countArgs(const Args&... args) {
return sizeof...(args);
}
static_assert(countArgs(1, 2, 3) == 3);
16.3 折叠表达式(C++17)
// 一元折叠
template <typename... Args>
auto sum(Args... args) {
return (args + ...); // 右折叠
}
// 二元折叠
template <typename... Args>
auto sum(Args... args) {
return (args + ... + 0); // 空参数包时返回 0
}
// 逗号折叠
template <typename... Args>
void print(const Args&... args) {
((std::cout << args << " "), ...);
std::cout << std::endl;
}
第五部分:STL 标准库
第十七章:容器
17.1 序列容器
#include <vector>
#include <deque>
#include <list>
#include <forward_list>
#include <array>
// vector - 动态数组
std::vector<int> v = {1, 2, 3, 4, 5};
v.push_back(6);
v.pop_back();
v[0]; // 不检查边界
v.at(0); // 检查边界
v.size();
v.empty();
v.clear();
v.begin(); // 迭代器
v.end();
// deque - 双端队列
std::deque<int> dq = {1, 2, 3};
dq.push_front(0);
dq.push_back(4);
dq.pop_front();
dq.pop_back();
// list - 双向链表
std::list<int> lst = {1, 2, 3};
lst.push_front(0);
lst.push_back(4);
lst.insert(lst.begin(), -1);
lst.remove(2); // 删除所有值为 2 的元素
// forward_list - 单向链表
std::forward_list<int> flst = {1, 2, 3};
flst.push_front(0);
// array - 固定大小数组
std::array<int, 5> arr = {1, 2, 3, 4, 5};
arr.size();
arr[0];
17.2 关联容器
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
// set - 有序集合
std::set<int> s = {3, 1, 4, 1, 5}; // {1, 3, 4, 5}
s.insert(2);
s.erase(3);
s.count(4); // 1(存在)
s.count(10); // 0(不存在)
s.find(4); // 迭代器
// multiset - 允许重复的有序集合
std::multiset<int> ms = {1, 1, 2, 2, 3};
ms.count(1); // 2
// map - 有序映射
std::map<std::string, int> m;
m["apple"] = 1;
m["banana"] = 2;
m.insert({"cherry", 3});
m.at("apple"); // 1
m.count("banana"); // 1
m.find("cherry"); // 迭代器
// unordered_set - 哈希集合
std::unordered_set<int> us = {1, 2, 3};
us.insert(4);
us.count(2); // 1
// unordered_map - 哈希映射
std::unordered_map<std::string, int> um;
um["key"] = 42;
um.at("key");
17.3 容器适配器
#include <stack>
#include <queue>
// stack - 栈
std::stack<int> stk;
stk.push(1);
stk.push(2);
stk.top(); // 2
stk.pop();
// queue - 队列
std::queue<int> q;
q.push(1);
q.push(2);
q.front(); // 1
q.back(); // 2
q.pop();
// priority_queue - 优先队列(最大堆)
std::priority_queue<int> pq;
pq.push(3);
pq.push(1);
pq.push(4);
pq.top(); // 4
pq.pop();
// 最小堆
std::priority_queue<int, std::vector<int>, std::greater<int>> min_pq;
第十八章:迭代器
18.1 迭代器类型
| 类型 |
说明 |
支持的操作 |
| 输入迭代器 |
只读,单向 |
*it, ++it |
| 输出迭代器 |
只写,单向 |
*it = value, ++it |
| 前向迭代器 |
读写,单向 |
*it, ++it |
| 双向迭代器 |
读写,双向 |
*it, ++it, --it |
| 随机访问迭代器 |
读写,随机访问 |
*it, it+n, it-n, it[i] |
18.2 迭代器使用
std::vector<int> v = {1, 2, 3, 4, 5};
// 正向迭代
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
// 反向迭代
for (auto it = v.rbegin(); it != v.rend(); ++it) {
std::cout << *it << " ";
}
// const 迭代器
for (auto it = v.cbegin(); it != v.cend(); ++it) {
// *it = 10; // 错误!
std::cout << *it << " ";
}
// 范围 for(C++11)
for (const auto& item : v) {
std::cout << item << " ";
}
18.3 迭代器辅助函数
#include <iterator>
std::vector<int> v = {1, 2, 3, 4, 5};
// advance - 移动迭代器
auto it = v.begin();
std::advance(it, 3); // it 现在指向第 4 个元素
// distance - 计算距离
auto d = std::distance(v.begin(), v.end()); // d = 5
// next / prev
auto it2 = std::next(v.begin(), 2); // 指向第 3 个元素
auto it3 = std::prev(v.end(), 1); // 指向最后一个元素
// inserter, back_inserter, front_inserter
std::vector<int> v2;
std::copy(v.begin(), v.end(), std::back_inserter(v2));
第十九章:算法
19.1 非修改序列操作
#include <algorithm>
std::vector<int> v = {1, 2, 3, 4, 5};
// 查找
auto it = std::find(v.begin(), v.end(), 3);
auto it2 = std::find_if(v.begin(), v.end(), [](int x) { return x > 3; });
auto count = std::count(v.begin(), v.end(), 3);
auto count2 = std::count_if(v.begin(), v.end(), [](int x) { return x > 3; });
// 检查
bool all = std::all_of(v.begin(), v.end(), [](int x) { return x > 0; });
bool any = std::any_of(v.begin(), v.end(), [](int x) { return x > 3; });
bool none = std::none_of(v.begin(), v.end(), [](int x) { return x > 10; });
// 遍历
std::for_each(v.begin(), v.end(), [](int& x) { x *= 2; });
// 搜索
auto it3 = std::search(v.begin(), v.end(), {3, 4, 5});
auto it4 = std::adjacent_find(v.begin(), v.end());
19.2 修改序列操作
// 复制
std::vector<int> v2(v.size());
std::copy(v.begin(), v.end(), v2.begin());
std::copy_if(v.begin(), v.end(), v2.begin(), [](int x) { return x > 3; });
// 移动
std::vector<int> v3(v.size());
std::move(v.begin(), v.end(), v3.begin());
// 变换
std::transform(v.begin(), v.end(), v2.begin(), [](int x) { return x * 2; });
// 替换
std::replace(v.begin(), v.end(), 3, 30);
std::replace_if(v.begin(), v.end(), [](int x) { return x < 3; }, 0);
// 填充
std::fill(v.begin(), v.end(), 0);
std::fill_n(v.begin(), 5, 42);
// 生成
std::generate(v.begin(), v.end(), []() { return rand() % 100; });
// 删除
auto new_end = std::remove(v.begin(), v.end(), 3);
v.erase(new_end, v.end());
// 去重
std::sort(v.begin(), v.end());
auto last = std::unique(v.begin(), v.end());
v.erase(last, v.end());
// 反转
std::reverse(v.begin(), v.end());
// 旋转
std::rotate(v.begin(), v.begin() + 2, v.end());
// 随机打乱
std::random_shuffle(v.begin(), v.end()); // C++14 前
std::shuffle(v.begin(), v.end(), std::mt19937(std::random_device()())); // C++11
// 分区
auto mid = std::partition(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
19.3 排序
std::vector<int> v = {5, 3, 1, 4, 2};
// 排序
std::sort(v.begin(), v.end());
std::sort(v.begin(), v.end(), std::greater<int>()); // 降序
// 稳定排序
std::stable_sort(v.begin(), v.end());
// 部分排序
std::partial_sort(v.begin(), v.begin() + 3, v.end());
// 第 n 大元素
std::nth_element(v.begin(), v.begin() + 2, v.end());
// 二分查找(需要已排序)
bool found = std::binary_search(v.begin(), v.end(), 3);
auto lb = std::lower_bound(v.begin(), v.end(), 3);
auto ub = std::upper_bound(v.begin(), v.end(), 3);
auto range = std::equal_range(v.begin(), v.end(), 3);
// 合并(需要已排序)
std::vector<int> v1 = {1, 3, 5};
std::vector<int> v2 = {2, 4, 6};
std::vector<int> v3(v1.size() + v2.size());
std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
19.4 数值算法
#include <numeric>
std::vector<int> v = {1, 2, 3, 4, 5};
// 累加
int sum = std::accumulate(v.begin(), v.end(), 0);
// 内积
int dot = std::inner_product(v.begin(), v.end(), v.begin(), 0);
// 部分和
std::vector<int> partial(v.size());
std::partial_sum(v.begin(), v.end(), partial.begin());
// 相邻差
std::vector<int> diff(v.size());
std::adjacent_difference(v.begin(), v.end(), diff.begin());
// iota - 填充递增序列
std::vector<int> v2(10);
std::iota(v2.begin(), v2.end(), 1); // 1, 2, 3, ..., 10
// reduce(C++17)
int sum2 = std::reduce(v.begin(), v.end(), 0);
// transform_reduce(C++17)
int sum3 = std::transform_reduce(v.begin(), v.end(), 0, std::plus<>(),
[](int x) { return x * x; });
第二十章:函数对象与 Lambda
20.1 函数对象(仿函数)
struct Adder {
int value;
Adder(int v) : value(v) {}
int operator()(int x) const {
return x + value;
}
};
Adder add5(5);
int result = add5(10); // 15
// 用于算法
std::vector<int> v = {1, 2, 3, 4, 5};
std::transform(v.begin(), v.end(), v.begin(), Adder(10));
20.2 标准函数对象
#include <functional>
// 算术
std::plus<int> add;
std::minus<int> sub;
std::multiplies<int> mul;
std::divides<int> div;
std::negate<int> neg;
std::modulus<int> mod;
// 比较
std::equal_to<int> eq;
std::not_equal_to<int> neq;
std::greater<int> gt;
std::less<int> lt;
std::greater_equal<int> ge;
std::less_equal<int> le;
// 逻辑
std::logical_and<int> land;
std::logical_or<int> lor;
std::logical_not<int> lnot;
// 使用
std::sort(v.begin(), v.end(), std::greater<int>());
int sum = std::accumulate(v.begin(), v.end(), 0, std::plus<int>());
20.3 std::function
#include <functional>
// 存储任何可调用对象
std::function<int(int, int)> func;
func = [](int a, int b) { return a + b; };
int r1 = func(3, 4); // 7
func = std::plus<int>();
int r2 = func(3, 4); // 7
int add(int a, int b) { return a + b; }
func = add;
int r3 = func(3, 4); // 7
20.4 std::bind
#include <functional>
int add(int a, int b) { return a + b; }
// 绑定参数
auto add5 = std::bind(add, std::placeholders::_1, 5);
int r = add5(10); // 15
// 绑定成员函数
class MyClass {
public:
void print(const std::string& msg) { std::cout << msg << std::endl; }
};
MyClass obj;
auto printFunc = std::bind(&MyClass::print, &obj, std::placeholders::_1);
printFunc("Hello");
第六部分:内存管理
第二十一章:栈与堆
21.1 内存区域
┌──────────────────┐ 高地址
│ 栈 │ ← 局部变量、函数参数
│ ↓ │
│ │
│ ↑ │
│ 堆 │ ← new/malloc
├──────────────────┤
│ 全局/静态 │ ← 全局变量、静态变量
├──────────────────┤
│ 代码段 │ ← 程序代码
└──────────────────┘ 低地址
21.2 动态内存分配
// new / delete
int* p = new int(42);
delete p;
// 数组
int* arr = new int[10];
delete[] arr;
// 不抛出异常的版本
int* p2 = new(std::nothrow) int(42);
if (p2) {
// 分配成功
delete p2;
}
// placement new
char buffer[sizeof(int)];
int* p3 = new(buffer) int(42); // 在指定内存位置构造
第二十二章:智能指针
22.1 unique_ptr(C++11)
#include <memory>
// 创建
std::unique_ptr<int> p1 = std::make_unique<int>(42); // C++14
std::unique_ptr<int> p2(new int(42));
// 不能拷贝,只能移动
// std::unique_ptr<int> p3 = p1; // 错误!
std::unique_ptr<int> p3 = std::move(p1); // 正确
// 访问
int value = *p2;
int* raw = p2.get(); // 获取原始指针
// 数组
std::unique_ptr<int[]> arr = std::make_unique<int[]>(10);
// 自定义删除器
auto deleter = [](FILE* f) { fclose(f); };
std::unique_ptr<FILE, decltype(deleter)> file(fopen("test.txt", "r"), deleter);
22.2 shared_ptr(C++11)
// 创建
std::shared_ptr<int> p1 = std::make_shared<int>(42);
std::shared_ptr<int> p2(new int(42));
// 可以拷贝
std::shared_ptr<int> p3 = p1; // 引用计数 +1
// 引用计数
p1.use_count(); // 2(p1 和 p3)
// 重置
p1.reset(); // 引用计数 -1
// 循环引用问题
struct Node {
std::shared_ptr<Node> next; // 循环引用!
};
22.3 weak_ptr(C++11)
// 解决循环引用
struct Node {
std::weak_ptr<Node> next; // 弱引用
~Node() { std::cout << "Destroyed" << std::endl; }
};
std::shared_ptr<Node> node1 = std::make_shared<Node>();
std::shared_ptr<Node> node2 = std::make_shared<Node>();
node1->next = node2;
node2->next = node1;
// 使用 weak_ptr
std::weak_ptr<int> wp = p1;
if (auto sp = wp.lock()) {
// sp 是 shared_ptr
int value = *sp;
}
第二十三章:移动语义
23.1 右值引用(C++11)
int a = 10;
int& lref = a; // 左值引用
int&& rref = 10; // 右值引用
int&& rref2 = std::move(a); // 将 a 转为右值
23.2 移动构造函数
class Buffer {
int* data_;
size_t size_;
public:
// 移动构造函数
Buffer(Buffer&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}
// 移动赋值运算符
Buffer& operator=(Buffer&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}
};
23.3 完美转发(C++11)
template <typename T>
void wrapper(T&& arg) {
// std::forward 保持参数的值类别
target(std::forward<T>(arg));
}
// 使用
wrapper(42); // arg 是右值引用
int x = 10;
wrapper(x); // arg 是左值引用
wrapper(std::move(x)); // arg 是右值引用
第七部分:异常处理
第二十四章:异常机制
24.1 基本语法
try {
// 可能抛出异常的代码
throw std::runtime_error("Something went wrong");
}
catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "Unknown exception" << std::endl;
}
24.2 标准异常类
std::exception
├── std::logic_error
│ ├── std::invalid_argument
│ ├── std::domain_error
│ ├── std::length_error
│ └── std::out_of_range
├── std::runtime_error
│ ├── std::range_error
│ ├── std::overflow_error
│ └── std::underflow_error
└── std::bad_alloc
24.3 自定义异常
class MyException : public std::exception {
std::string message_;
public:
MyException(const std::string& msg) : message_(msg) {}
const char* what() const noexcept override {
return message_.c_str();
}
};
// 使用
throw MyException("Custom error");
24.4 noexcept
// 声明函数不抛出异常
void safeFunction() noexcept {
// 这个函数保证不抛出异常
}
// 条件 noexcept
template <typename T>
void swap(T& a, T& b) noexcept(noexcept(T(std::move(a)))) {
T temp = std::move(a);
a = std::move(b);
b = std::move(temp);
}
第八部分:并发编程
第二十五章:线程
25.1 基本线程
#include <thread>
void printHello() {
std::cout << "Hello from thread" << std::endl;
}
// 创建线程
std::thread t(printHello);
t.join(); // 等待线程结束
// 带参数
void printNumber(int n) {
std::cout << "Number: " << n << std::endl;
}
std::thread t2(printNumber, 42);
t2.join();
// Lambda
std::thread t3([]() {
std::cout << "Lambda thread" << std::endl;
});
t3.join();
// detach
std::thread t4(printHello);
t4.detach(); // 分离线程
25.2 线程管理
std::thread t(printHello);
// 检查线程是否可 join
if (t.joinable()) {
t.join();
}
// 获取线程 ID
std::thread::id id = t.get_id();
// 获取硬件并发数
unsigned int n = std::thread::hardware_concurrency();
第二十六章:互斥锁与原子操作
26.1 互斥锁
#include <mutex>
std::mutex mtx;
int shared_data = 0;
void increment() {
mtx.lock();
shared_data++;
mtx.unlock();
}
// RAII 风格
void incrementSafe() {
std::lock_guard<std::mutex> lock(mtx);
shared_data++;
// 自动解锁
}
// unique_lock(更灵活)
void incrementFlexible() {
std::unique_lock<std::mutex> lock(mtx);
shared_data++;
lock.unlock(); // 手动解锁
// ...
lock.lock(); // 重新加锁
}
// std::scoped_lock(C++17)
std::mutex mtx1, mtx2;
void transfer() {
std::scoped_lock lock(mtx1, mtx2); // 同时锁定多个互斥量
// ...
}
26.2 原子操作
#include <atomic>
std::atomic<int> counter(0);
void increment() {
counter++; // 原子操作
counter.fetch_add(1);
}
// 原子标志
std::atomic_flag flag = ATOMIC_FLAG_INIT;
bool expected = false;
flag.test_and_set();
flag.clear();
第二十七章:条件变量与异步
27.1 条件变量
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void producer() {
std::lock_guard<std::mutex> lock(mtx);
ready = true;
cv.notify_one(); // 通知一个等待线程
}
void consumer() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; }); // 等待条件满足
// ...
}
27.2 std::future 和 std::promise
#include <future>
// promise/future
std::promise<int> prom;
std::future<int> fut = prom.get_future();
std::thread t([&prom]() {
prom.set_value(42);
});
int result = fut.get(); // 阻塞等待
t.join();
// async
std::future<int> fut2 = std::async(std::launch::async, []() {
return 42;
});
int result2 = fut2.get();
// packaged_task
std::packaged_task<int(int, int)> task([](int a, int b) {
return a + b;
});
std::future<int> fut3 = task.get_future();
std::thread t2(std::move(task), 3, 4);
int result3 = fut3.get();
t2.join();
第九部分:现代 C++ 特性
第二十八章:C++11 新特性
| 特性 |
说明 |
auto |
类型推导 |
decltype |
类型推导(表达式) |
nullptr |
空指针常量 |
范围 for |
for (auto& x : container) |
| Lambda |
匿名函数 |
constexpr |
编译期常量表达式 |
| 初始化列表 |
std::initializer_list |
| 右值引用 |
T&& |
| 移动语义 |
移动构造/赋值 |
| 完美转发 |
std::forward |
unique_ptr |
独占所有权智能指针 |
shared_ptr |
共享所有权智能指针 |
weak_ptr |
弱引用智能指针 |
std::function |
通用函数包装器 |
std::bind |
参数绑定 |
std::thread |
线程支持 |
std::mutex |
互斥锁 |
std::atomic |
原子操作 |
std::future |
异步结果 |
enum class |
作用域枚举 |
override |
显式重写标记 |
final |
禁止重写/继承 |
noexcept |
异常规范 |
static_assert |
编译期断言 |
| 用户定义字面量 |
operator"" |
| 原始字符串 |
R"(...)" |
第二十九章:C++14 新特性
| 特性 |
说明 |
| 泛型 Lambda |
[](auto a, auto b) |
| Lambda 捕获初始化 |
[x = std::move(x)] |
auto 返回类型 |
函数返回类型推导 |
decltype(auto) |
保留引用的推导 |
std::make_unique |
创建 unique_ptr |
| 二进制字面量 |
0b1010 |
| 数字分隔符 |
1'000'000 |
std::exchange |
交换并返回旧值 |
std::integer_sequence |
编译期整数序列 |
第三十章:C++17 新特性
| 特性 |
说明 |
std::optional |
可选值 |
std::variant |
类型安全的联合体 |
std::any |
任意类型 |
std::string_view |
字符串视图 |
| 结构化绑定 |
auto [x, y] = pair; |
if constexpr |
编译期条件 |
| 折叠表达式 |
(args + ...) |
std::filesystem |
文件系统 |
std::invoke |
统一调用 |
std::apply |
调用元组参数 |
std::byte |
字节类型 |
| 内联变量 |
inline static int x = 0; |
| 嵌套命名空间 |
namespace A::B::C {} |
std::scoped_lock |
RAII 多锁 |
std::shared_mutex |
共享互斥量 |
| 并行算法 |
std::execution::par |
if 和 switch 初始化 |
if (auto x = foo(); x > 0) |
第三十一章:C++20 新特性
| 特性 |
说明 |
| 概念(Concepts) |
模板约束 |
| 范围(Ranges) |
范围库 |
| 协程(Coroutines) |
协程支持 |
| 模块(Modules) |
模块系统 |
std::format |
格式化库 |
| 三路比较 |
<=> 运算符 |
consteval |
立即常量 |
constinit |
常量初始化 |
std::span |
数组视图 |
std::jthread |
可 join 的线程 |
std::latch |
闩锁 |
std::barrier |
屏障 |
std::counting_semaphore |
计数信号量 |
| 日历和时区 |
<chrono> 扩展 |
std::source_location |
源码位置 |
[[likely]] / [[unlikely]] |
分支预测提示 |
[[no_unique_address]] |
空基类优化 |
| 聚合初始化增强 |
允许派生类聚合初始化 |
| 模板 Lambda |
[]<typename T>(T x) |
第三十二章:C++23 新特性
| 特性 |
说明 |
std::expected |
期望值(错误处理) |
std::print |
打印函数 |
std::mdspan |
多维数组视图 |
std::generator |
生成器协程 |
std::flat_map |
平坦映射 |
std::flat_set |
平坦集合 |
std::stacktrace |
堆栈跟踪 |
std::generator |
协程生成器 |
if consteval |
编译期判断 |
std::to_underlying |
枚举转底层类型 |
std::unreachable |
不可达标记 |
std::byteswap |
字节序交换 |
std::is_scoped_enum |
作用域枚举检测 |
import std; |
标准库模块 |
第十部分:预处理与编译
第三十三章:预处理器
33.1 宏定义
#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
// 取消宏定义
#undef PI
// 多行宏
#define PRINT_INFO(name, age) \
std::cout << "Name: " << name << std::endl; \
std::cout << "Age: " << age << std::endl;
// 字符串化
#define STRINGIFY(x) #x
std::cout << STRINGIFY(Hello); // "Hello"
// 拼接
#define CONCAT(a, b) a##b
int xy = 10; // CONCAT(x, y) = xy
33.2 条件编译
#if defined(DEBUG)
std::cout << "Debug mode" << std::endl;
#elif defined(RELEASE)
std::cout << "Release mode" << std::endl;
#else
std::cout << "Unknown mode" << std::endl;
#endif
// 头文件保护
#ifndef MY_HEADER_H
#define MY_HEADER_H
// ...
#endif
// 更简洁的方式
#pragma once
33.3 预定义宏
__FILE__ // 当前文件名
__LINE__ // 当前行号
__func__ // 当前函数名
__DATE__ // 编译日期
__TIME__ // 编译时间
__cplusplus // C++ 标准版本
__STDCPP_STRICT_POINTER_SAFETY__ // 指针安全
第三十四章:编译与链接
34.1 编译过程
源代码 (.cpp)
↓ 预处理
预处理后的代码
↓ 编译
汇编代码 (.s)
↓ 汇编
目标文件 (.o)
↓ 链接
可执行文件
34.2 链接
// 外部链接(默认)
int global_var = 10;
void func() {}
// 内部链接
static int internal_var = 20;
static void internal_func() {}
// 匿名命名空间
namespace {
int anon_var = 30;
void anon_func() {}
}
34.3 extern "C"
// C 链接(与 C 语言兼容)
extern "C" {
void c_function();
int c_variable;
}
// 混合使用
#ifdef __cplusplus
extern "C" {
#endif
void compatible_function();
#ifdef __cplusplus
}
#endif
第十一部分:文件与流
第三十五章:文件 I/O
#include <fstream>
// 写入文件
std::ofstream outfile("test.txt");
if (outfile.is_open()) {
outfile << "Hello, World!" << std::endl;
outfile << 42 << std::endl;
outfile.close();
}
// 读取文件
std::ifstream infile("test.txt");
if (infile.is_open()) {
std::string line;
while (std::getline(infile, line)) {
std::cout << line << std::endl;
}
infile.close();
}
// 读写模式
std::fstream file("test.txt", std::ios::in | std::ios::out | std::ios::app);
// 二进制文件
std::ofstream binfile("data.bin", std::ios::binary);
int data[] = {1, 2, 3, 4, 5};
binfile.write(reinterpret_cast<char*>(data), sizeof(data));
binfile.close();
std::ifstream bininfile("data.bin", std::ios::binary);
int read_data[5];
bininfile.read(reinterpret_cast<char*>(read_data), sizeof(read_data));
bininfile.close();
// 文件位置
infile.seekg(0, std::ios::beg); // 移到开头
infile.seekg(0, std::ios::end); // 移到结尾
infile.tellg(); // 获取当前位置
// 文件状态
infile.eof(); // 是否到文件末尾
infile.fail(); // 是否失败
infile.good(); // 是否正常
infile.clear(); // 清除错误状态
第三十六章:字符串流
#include <sstream>
// 字符串输出流
std::ostringstream oss;
oss << "Name: " << "Alice" << ", Age: " << 30;
std::string result = oss.str(); // "Name: Alice, Age: 30"
// 字符串输入流
std::istringstream iss("42 3.14 Hello");
int i;
double d;
std::string s;
iss >> i >> d >> s; // i=42, d=3.14, s="Hello"
// 类型转换
std::string num_str = "123";
int num;
std::istringstream(num_str) >> num;
// 格式化输出
std::ostringstream formatted;
formatted << std::fixed << std::setprecision(2) << 3.14159;
std::string pi_str = formatted.str(); // "3.14"
// 使用 std::format(C++20)
// std::string s = std::format("Name: {}, Age: {}", "Alice", 30);
附录:C++ 关键字完整列表
alignas alignof and and_eq
asm auto bitand bitor
bool break case catch
char char8_t char16_t char32_t
class compl concept const
consteval constexpr constinit const_cast
continue co_await co_return co_yield
decltype default delete do
double dynamic_cast else enum
explicit export extern false
float for friend goto
if inline int long
mutable namespace new noexcept
not not_eq nullptr operator
or or_eq private protected
public register reinterpret_cast
requires return short signed
sizeof static static_assert static_cast
struct switch template this
thread_local throw true try
typedef typeid typename union
unsigned using virtual void
volatile wchar_t while xor
xor_eq