一、 容器分类与特性
1. 顺序容器有哪些?
- 类型:
vector、deque、list、forward_list、array、string。 - 特点与底层结构:
vector:动态数组,连续内存,支持随机访问,尾插尾删快。deque:双端队列,分段连续内存,支持随机访问,头尾插入删除都快。list:双向链表,非连续内存,不支持随机访问,任意位置插入删除快。forward_list:单向链表,内存开销更小,只支持单向遍历。
- 常用操作:
push_back、pop_back、insert、erase、size、clear等(forward_list提供push_front和pop_front,没有size())。 - 迭代器失效情况:
vector/string:扩容时全部失效;插入或删除元素时,该位置之后的迭代器失效。deque:在首尾之外的位置插入或删除元素,会导致所有迭代器失效。list/forward_list:插入元素不会失效,删除元素仅导致被删元素的迭代器失效。
2. 有序关联式容器有哪些?
- 类型:
map、set、multimap、multiset。 - 特点与底层结构:底层为红黑树(一种自平衡二叉搜索树)。元素自动按 key 排序(默认升序),查找、插入、删除的时间复杂度为 O(log n)。
- 常用操作:
insert、erase、find、count、lower_bound、upper_bound等。
3. 无序关联式容器有哪些?
- 类型:
unordered_map、unordered_set、unordered_multimap、unordered_multiset。 - 特点与底层结构:底层为哈希表。元素无序,平均查找、插入、删除时间复杂度为 O(1),最坏情况 O(n)(哈希冲突严重时)。
- 常用操作:与有序容器类似,额外提供了桶操作(如
bucket_count、load_factor等)。
4. 容器适配器有哪些?
- 类型:
stack(栈)、queue(队列)、priority_queue(优先队列)。 - 特点:不是独立的容器,而是基于底层容器(如
deque、vector、list)封装出的特定接口。 - 常用操作:
push、pop、top(queue为front/back)、empty、size。
二、 迭代器与算法
5. 迭代器有哪些?
- 按操作分类:输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器。
- 不同容器获取的迭代器类型:
vector/deque/array:随机访问迭代器。list/map/set:双向迭代器。forward_list/unordered_*:前向迭代器。
6. 常见的算法有哪些?
- 非修改序列算法:
find、count、for_each、equal、search。 - 修改序列算法:
copy、replace、remove、transform、fill。 - 排序与查找:
sort、stable_sort、binary_search、lower_bound。 - 数值算法:
accumulate、inner_product。
7. 迭代器适配器中,插入迭代器有哪些?
- 类型:
back_inserter(尾插)、front_inserter(头插)、inserter(指定位置插)。 - 特点:通过赋值操作将元素插入容器,而不是覆盖原有元素。
三、 Lambda 与 函数对象
8. lambda表达式语法是什么?
- 语法:
[捕获列表](参数列表) mutable 异常说明 -> 返回类型 { 函数体 }。 - 值捕获和引用捕获的区别:
- 值捕获:拷贝外部变量,lambda 内部默认不可修改(加
mutable可修改,但改的是副本),生命周期独立。 - 引用捕获:直接引用外部变量,修改会影响外部,需注意悬垂引用(外部变量生命周期结束)。
- 值捕获:拷贝外部变量,lambda 内部默认不可修改(加
- lambda如何调用?:定义后,像普通函数一样通过
()调用,通常配合auto关键字使用:auto f = [](int x){ return x; }; f(10);。
9. bind的作用是什么?
- 作用:
std::bind用于绑定可调用对象的部分参数,生成一个新的可调用对象(使用std::placeholders::_1等占位符)。 - 可以绑定哪些可调用对象?:普通函数、函数指针、成员函数指针、Lambda 表达式、函数对象(仿函数)。
四、 现代 C++ 特性与底层机制
10. 引用折叠的规则是什么?
- 规则:只有右值引用的右值引用折叠为右值引用(
T&& &&->T&&)。 - 其他组合全部折叠为左值引用:
T& &->T&,T& &&->T&,T&& &->T&。 - 这是实现完美转发(
std::forward)和移动语义的基础。
11. std::function有什么作用?
- 是一个通用的多态函数包装器。它可以存储、复制和调用任何可调用对象(普通函数、Lambda、bind 表达式、函数对象等)。它使得我们可以用统一的方式处理不同类型的可调用实体(常用于回调函数)。
12. std::mem_fn有什么作用?
- 将成员函数指针转换为一个可调用对象。它允许成员函数像普通函数一样被算法或
std::function调用(例如std::mem_fn(&Class::func))。
13. 可调用实体都有哪些?
- 普通函数与函数指针。
- Lambda 表达式。
- 函数对象(重载了
operator()的类对象,也称仿函数)。 std::bind返回的对象。- 成员函数指针。