在传统 C++ 中,数组与 vector 的抉择常让人纠结:数组缺乏安全检查,vector 存在动态扩容开销。C++11 引入的std::array
完美平衡了两者优势:
特性解析:
代码示例:
#include
#include
#include
int main() {
// 初始化与基本操作
std::array arr = {1, 3, 2, 4};
std::cout << "数组大小:" << arr.size() << std::endl;
// 迭代器与算法支持
std::sort(arr.begin(), arr.end());
for (const auto& num : arr) {
std::cout << num << " ";
}
// 与C接口兼容
int* c_ptr = arr.data();
return 0;
}
与双向链表std::list
相比,std::forward_list
采用单向链表实现,牺牲反向遍历能力换取更紧凑的内存布局:
核心优势:
典型应用:
#include
int main() {
std::forward_list flist;
flist.push_front(1);
flist.push_front(2);
// 遍历与删除
auto it = flist.begin();
if (it != flist.end()) {
flist.erase_after(it); // 删除头节点后的元素
}
// 合并链表
std::forward_list another = {3, 4};
flist.merge(another);
return 0;
}
传统std::map
/std::set
基于红黑树实现,插入与查找复杂度为 O (logN)。C++11 引入的无序容器基于哈希表,平均复杂度降至 O (1):
以std::unordered_map
为例,与std::map
的关键差异:
特性 | std::map | std::unordered_map |
---|---|---|
底层结构 | 红黑树 | 哈希表 + 链表(解决冲突) |
插入复杂度 | O(logN) | 平均 O (1),最坏 O (N) |
遍历顺序 | 按键有序 | 无固定顺序 |
内存开销 | 每个节点含左右指针 | 哈希桶 + 链表指针 |
适用场景 | 需有序遍历、范围查询 | 高频查找、无序存储 |
#include
#include
struct Person {
std::string name;
int age;
bool operator==(const Person& other) const {
return name == other.name && age == other.age;
}
};
// 为自定义类型特化哈希函数
namespace std {
template<>
struct hash {
size_t operator()(const Person& p) const {
return hash()(p.name) ^ (hash()(p.age) << 1);
}
};
}
int main() {
std::unordered_map person_map;
return 0;
}
reserve(n)
避免动态扩容导致的重哈希;std::unordered_map
的max_load_factor
调整负载因子;传统std::pair
仅能存储两个元素,std::tuple
则支持任意数量、任意类型的元素组合:
#include
#include
int main() {
// 创建元组
auto student = std::make_tuple(95, 'A', "张三");
// 访问元素(编译期索引)
int score = std::get<0>(student);
char grade = std::get<1>(student);
// 结构化绑定(C++17特性)
auto [s, g, name] = student;
std::cout << "姓名:" << name << ",成绩:" << s << std::endl;
// 元组合并
auto new_tuple = std::tuple_cat(student, std::make_tuple(18));
return 0;
}
C++17 引入的std::variant
配合元组,实现运行期动态索引:
#include
#include
#include
// 运行期索引元组元素
template
constexpr std::variant tuple_at(const std::tuple& tpl, size_t index) {
if constexpr (N >= sizeof...(T)) {
throw std::out_of_range("索引越界");
}
if (index == N) {
return std::variant{std::in_place_index, std::get(tpl)};
}
return tuple_at<(N < sizeof...(T) - 1 ? N + 1 : 0)>(tpl, index);
}
int main() {
auto t = std::make_tuple(10, "hello", 3.14);
size_t idx = 1;
std::visit([](auto&& x) { std::cout << x << std::endl; }, tuple_at<0>(t, idx));
return 0;
}
按场景选容器:
std::map
/std::set
;std::unordered_map
/std::unordered_set
;std::array
;std::forward_list
。性能优化 Tips:
std::vector
预留空间:reserve()
避免多次扩容;emplace_back
替代push_back
+ 构造;std::unordered_map
,合理设置哈希函数与负载因子;std::move
避免拷贝。