c++小巧思

make_shared

make_shared 是一个函数模板,它的语法

cpp 复制代码
std::make_shared<类型名>(构造函数的参数)
//               模板参数   函数参数
//  make_shared 调用
make_shared<LruNodeType>(Key(), Value());
//         告诉它创建什么  传给构造函数的参数

make_unique

cpp 复制代码
std::make_unique<类型名>(构造参数)

容器常用函数

cpp 复制代码
// 1. 大小相关
container.size();        // 返回元素个数
container.empty();       // 是否为空

// 2. 清空
container.clear();       // 删除所有元素

// 3. 迭代器
container.begin();       // 第一个元素的迭代器
container.end();         // 最后一个元素的下一个位置

顺序容器(vector, list, deque)

cpp 复制代码
vector<int> v;

// 添加
v.push_back(10);         // 尾部添加
v.push_front(10);        // 头部添加(list支持)
v.insert(pos, 10);       // 指定位置插入

// 删除
v.pop_back();            // 删除尾部
v.pop_front();           // 删除头部(list支持)
v.erase(pos);            // 删除指定位置
v.erase(begin, end);     // 删除范围

// 访问
v[0];                    // 下标访问(vector, deque)
v.at(0);                 // 边界检查的下标访问
v.front();               // 第一个元素
v.back();                // 最后一个元素
  1. vector(动态数组)
cpp 复制代码
vector<int> v = {1, 2, 3};

// ✅ 支持
v.push_back(4);     // 尾部添加:{1,2,3,4}
v.pop_back();       // 尾部删除:{1,2,3}
v.insert(v.begin() + 1, 10);  // {1,10,2,3}
v.erase(v.begin()); // 删除第一个:{10,2,3}
cout << v[0];       // 下标访问:10
cout << v.at(0);    // 边界检查访问:10
cout << v.front();  // 第一个元素:10
cout << v.back();   // 最后一个元素:3

// ❌ 不支持
v.push_front(0);    // 编译错误!vector没有push_front
v.pop_front();      // 编译错误!vector没有pop_front

vector在内存中是连续存储的,头部插入/删除需要移动所有元素,效率低,所以没提供。

  1. deque(双端队列)
cpp 复制代码
deque<int> d = {2, 3, 4};

// ✅ 全部支持!
d.push_front(1);    // {1,2,3,4}
d.push_back(5);     // {1,2,3,4,5}
d.pop_front();      // {2,3,4,5}
d.pop_back();       // {2,3,4}
cout << d[0];       // 下标访问:2
cout << d.at(0);    // 边界检查:2
cout << d.front();  // 第一个:2
cout << d.back();   // 最后一个:4

deque是"分段连续"的,两端操作都很快,所以两端操作都支持

  1. list(双向链表)
cpp 复制代码
list<int> l = {2, 3, 4};

// ✅ 支持两端操作
l.push_front(1);    // {1,2,3,4}
l.push_back(5);     // {1,2,3,4,5}
l.pop_front();      // {2,3,4,5}
l.pop_back();       // {2,3,4}

// ✅ 支持插入删除
auto it = l.begin();
advance(it, 1);     // 指向第二个元素
l.insert(it, 10);   // {2,10,3,4}
l.erase(it);        // 删除10:{2,3,4}

// ❌ 不支持随机访问
cout << l[0];       // 编译错误!list没有[]
cout << l.at(0);    // 编译错误!
cout << l.back();   // ✅ 支持,返回最后一个:4

list是链表,节点不连续,无法用下标访问。

  1. forward_list(单向链表,C++11)
cpp 复制代码
forward_list<int> f = {2, 3, 4};

// ✅ 只支持头部操作
f.push_front(1);    // {1,2,3,4}
f.pop_front();      // {2,3,4}

// ⚠️ 特殊的插入删除(在指定位置之后)
auto it = f.begin();  // 指向2
f.insert_after(it, 10);  // 在2后面插入:{2,10,3,4}
f.erase_after(it);      // 删除10:{2,3,4}

// ❌ 不支持
f.push_back(5);     // 编译错误!
f.pop_back();       // 编译错误!
cout << f.back();   // 编译错误!没有back()

最节省内存的链表,但功能最少

关联容器(map, unordered_map)

cpp 复制代码
unordered_map<int, string> m;

// 添加/修改
m[1] = "apple";          // 如果key存在就修改,不存在就添加
m.insert({2, "banana"}); // 插入,如果key已存在则失败

// 查找
auto it = m.find(1);     // 返回迭代器,找不到返回 m.end()
if (it != m.end()) {
    // 找到了
    int key = it->first;
    string value = it->second;
}

// 检查是否存在
if (m.count(1)) {        // 返回1(存在)或0(不存在)
    // key存在
}

// 删除
m.erase(1);              // 删除key=1的元素
m.erase(it);             // 删除迭代器指向的元素

// 遍历
for (auto& [key, value] : m) {
    cout << key << ": " << value << endl;
}

关联容器分为两大类:有序关联容器(红黑树)和无序关联容器(哈希表)。

cpp 复制代码
// 有序关联容器(红黑树实现,自动排序)
set<int>           // 集合,元素唯一,自动排序
multiset<int>      // 集合,元素可重复,自动排序
map<int, string>   // 键值对,键唯一,自动按键排序
multimap<int, string> // 键值对,键可重复,自动按键排序

// 无序关联容器(哈希表实现,无顺序)
unordered_set<int>           // 哈希集合
unordered_multiset<int>      // 哈希集合(可重复)
unordered_map<int, string>   // 哈希映射
unordered_multimap<int, string> // 哈希映射(键可重复)

特殊容器(unique_ptr, shared_ptr)

cpp 复制代码
unique_ptr<int> u = make_unique<int>(10);

// unique_ptr 特有
if (u) {                 // 检查是否为空
    int value = *u;      // 解引用获取值
}
int* raw = u.get();      // 获取原始指针(危险,不推荐)
u.reset();               // 释放资源
u.reset(new int(20));    // 释放原资源,指向新资源
int* released = u.release(); // 放弃所有权,返回原始指针(记得delete)

// shared_ptr 额外功能
shared_ptr<int> s = make_shared<int>(10);
long count = s.use_count();  // 引用计数

// weak_ptr 的赋值操作
weak_ptr<Node> wp;
shared_ptr<Node> sp = make_shared<Node>();

wp = sp;     // ✅ weak_ptr 可以从 shared_ptr 赋值(自动转换)
wp = wp2;    // ✅ weak_ptr 可以从 weak_ptr 赋值

// 但要访问 weak_ptr 指向的对象:
sp = wp;     // ❌ 错误!不能直接转换
sp = wp.lock();  // ✅ 必须用 lock()

C++17的结构化绑定

C++17引入的结构化绑定,可以一次性把pair或tuple的元素拆开;

cpp 复制代码
for (auto& [key, value] : m) {
//        结构化绑定 (Structured Binding)
    cout << key << ": " << value << endl;
}

传统写法(C++11/14)

cpp 复制代码
unordered_map<int, string> m = {{1, "apple"}, {2, "banana"}};

// 方法1:用迭代器
for (auto it = m.begin(); it != m.end(); ++it) {
    int key = it->first;
    string value = it->second;
    cout << key << ": " << value << endl;
}

// 方法2:用auto(但还是需要.first和.second)
for (auto& pair : m) {
    cout << pair.first << ": " << pair.second << endl;
}

新写法(C++17)

cpp 复制代码
// 直接用结构化绑定拆开
for (auto& [key, value] : m) {
    cout << key << ": " << value << endl;
}
// 输出:
// 1: apple
// 2: banana

结构化绑定的更多用法

  1. 用于 pair
cpp 复制代码
pair<int, string> p = {1, "hello"};

// 传统方式
int a = p.first;
string b = p.second;

// 结构化绑定
auto [x, y] = p;
cout << x << ", " << y << endl;  // 输出:1, hello
  1. 用于 tuple
cpp 复制代码
tuple<int, double, string> t = {10, 3.14, "pi"};

// 传统方式
int i = get<0>(t);
double d = get<1>(t);
string s = get<2>(t);

// 结构化绑定
auto [i, d, s] = t;
cout << i << ", " << d << ", " << s << endl;  // 10, 3.14, pi
  1. 用于数组
cpp 复制代码
int arr[] = {1, 2, 3};
auto [a, b, c] = arr;
cout << a << b << c << endl;  // 输出:123
  1. 用于结构体
cpp 复制代码
struct Point {
    int x;
    int y;
};

Point p = {10, 20};
auto [x, y] = p;
cout << x << ", " << y << endl;  // 输出:10, 20

初始化

Value value{};

// 这是C++11的统一初始化语法

// 等价于:Value value = Value();

// 如果Value是int,value=0

// 如果Value是string,value=""

// 如果Value是自定义类,调用默认构造函数

奇怪函数

std::thread::hardware_concurrency() 返回CPU核心数(比如8核)

explicit FreqList(int n)

构造函数,explicit 关键字表示不能隐式转换。比如不能写 FreqList list = 5;,必须写 FreqList list(5);

node->pre.expired()

.expired()

weak_ptr 的内置方法:

返回 true:指向的对象已被销毁 / 过期

返回 false:指向的对象仍有效

next 和 prev 函数详解

std::next 和 std::prev 是 C++11 引入的迭代器辅助函数,用于安全地移动迭代器

帮你把迭代器往前或往后移动,特别是 list、set、map 这种不能直接 +1 的容器

list::splice 函数详解

splice 是 C++ std::list 的转移函数,可以把一个链表中的节点直接搬到另一个链表,不复制、不创建新节点,只是改指针。

splice 的四种形式

形式1:转移单个节点

cpp 复制代码
void splice(const_iterator position, list& other, const_iterator it);

参数:

position:目标位置(插入到这个位置之前)

other:源链表(从哪个链表转移)

it:要转移的节点(指向这个节点的迭代器)

形式2:转移单个节点(自己转移给自己)

cpp 复制代码
void splice(const_iterator position, list& other, const_iterator it);
// 如果 &other == this,可以重新排列链表

形式3:转移一个范围

cpp 复制代码
void splice(const_iterator position, list& other, 
            const_iterator first, const_iterator last);
            

参数:

position:目标位置

other:源链表

first, last:要转移的范围 [first, last)

形式4:转移整个链表

cpp 复制代码
void splice(const_iterator position, list& other);
参数:
position:目标位置
other:源链表(转移后变空)

splice 的重要特性1. 不复制、不移动2. 迭代器仍然有效3. 转移后源节点的迭代器失效(但指向新位置)

emplace_front 详解

emplace_front 是 std::list 的成员函数,在链表头部直接构造元素。emplace_front = 在头部创建新节点(不用提前创建对象)

make_pair 详解

make_pair 是 C++ 标准库函数,用于方便地创建 pair 对象。make_pair = 自动推导类型的 pair 创建工具

std::atomic 详解

std::atomic 是 C++11 引入的原子操作模板,用于多线程编程中无需加锁就能安全地访问共享变量。

atomic = 自动保证操作的"不可分割性",多线程访问时不会出现数据竞争

emplace_back:末尾造

emplace_front:头部造

emplace:任意位置造

emplace_after:forward_list 专用,后面造

emplace_hint:关联容器,带提示造

所有 emplace:直接在容器内存里 new 对象,不拷贝、不移动、更快。

cpp 复制代码
forward_list<int> flst;
auto it = flst.before_begin();
//before_begin () = 链表【第一个元素前面】的虚拟位置,它不指向任何元素,,只是给你用来在最前面插入 / 构造元素用的!
因为 C++ 有个容器叫 forward_list(单向链表),它只能往后插,不能往前插
唯一用途:专门给 insert_after / emplace_after 在头部插入元素
特点:不能用 *it 取值(它是空的);不能遍历;唯一作用:在链表最前面插入元素
相关推荐
Philtell11 小时前
漫谈学习之MapDiffusion算法学习
学习·mapdiffusion
郝学胜-神的一滴11 小时前
Qt 高级开发 017:中文乱码
开发语言·c++·qt·程序人生·用户界面
yanxiaoyu11012 小时前
小白学习深度学习、强化学习的相关重要内容
人工智能·深度学习·学习
上课不要睡觉了12 小时前
【统计法规】笔记目录
笔记·统计·统计师考试
晚风予卿云月12 小时前
【模拟】多项式输出 & 蛇形方阵 & 字符串展开
c++·算法·模拟算法·随笔·竞赛练习
-To be number.wan12 小时前
计算机组成原理 | 存储系统基本概念
学习·计算机组成原理
小羔羊的官方学习账号12 小时前
Claude Code学习笔记2 - Claude.md 文件和使用命令
笔记·ai·claude code
智者知已应修善业12 小时前
【51单片机按键加减1若不释放自动加减】2023-11-24
c++·经验分享·笔记·算法·51单片机
basketball61612 小时前
C++ 手写实现迭代器
开发语言·c++