在 C++ 标准库中,有多种数据结构可用于组合多个值,每种结构都有其特定的设计目的和适用场景。以下是主要组合数据结构的分类解析:
一、核心组合数据结构
1. std::pair (C++98)
用途:存储两个相关值(键值对、坐标点等)
特点:
固定大小(只能包含两个元素)
支持不同类型
支持比较操作(按 first 然后 second)
cpp
#include <utility>
// 创建 pair
auto point = std::make_pair(10, 20);
std::pair<std::string, int> person{"Alice", 30};
// 访问元素
std::cout << "X: " << point.first << ", Y: " << point.second;
2. std::tuple (C++11)
用途:存储固定数量的异构值(任意类型、任意数量)
特点:
类型安全的泛型结构
支持最多约 10 个元素(实现定义)
编译时类型检查
cpp
#include <tuple>
// 创建 tuple
auto data = std::make_tuple(42, "Hello", 3.14);
std::tuple<int, std::string, double> record(1, "Alice", 95.5);
// 访问元素(编译时索引)
auto id = std::get<0>(record);
auto name = std::get<1>(record);
// C++17 结构化绑定
auto [id, name, score] = record;
3. std::array (C++11)
用途:固定大小的同质数组(栈分配)
特点:
替代传统 C 风格数组
支持迭代器和标准容器操作
编译时已知大小
cpp
#include <array>
std::array<int, 5> numbers = {1, 2, 3, 4, 5};
// 访问元素
for (int n : numbers) {
std::cout << n << " ";
}
// 编译时大小检查
static_assert(numbers.size() == 5);
4. std::vector (C++98)
用途:动态大小的同质数组(堆分配)
特点:
最常用的顺序容器
自动内存管理
随机访问 O(1)
尾部插入/删除高效
cpp
#include <vector>
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
// 添加元素
names.push_back("David");
// 访问元素
std::cout << names[1]; // 输出 "Bob"
二、高级组合结构
5. std::variant (C++17)
用途:类型安全的联合体(存储多个类型中的一个)
特点:
替代 union 的安全方案
值语义(非指针)
可包含复杂类型(字符串、容器等)
cpp
#include <variant>
using Value = std::variant<int, double, std::string>;
Value v1 = 42;
Value v2 = 3.14;
Value v3 = "Hello";
// 访问值
std::visit([](auto&& arg) {
std::cout << arg;
}, v3);
// 检查当前类型
if (std::holds_alternative<int>(v1)) {
std::cout << "Integer: " << std::get<int>(v1);
}
6. std::any (C++17)
用途:存储任意类型的单个值
特点:
类似脚本语言的动态类型
运行时类型检查
需要显式类型转换
cpp
#include <any>
std::any data;
data = 42; // 存储 int
data = std::string("Hello"); // 替换为 string
// 安全访问
try {
std::string s = std::any_cast<std::string>(data);
} catch (const std::bad_any_cast& e) {
std::cerr << "Wrong type: " << e.what();
}
7. std::optional (C++17)
用途:表示可选值(可能有值或为空)
特点:
替代指针或特殊值(如 -1)表示缺失值
明确表达"可能有值"的语义
避免空指针异常
cpp
#include <optional>
std::optional<int> findValue(const std::vector<int>& vec, int target) {
for (int v : vec) {
if (v == target) return v;
}
return std::nullopt; // 空值
}
// 使用
auto result = findValue({1,2,3}, 2);
if (result) {
std::cout << "Found: " << *result;
} else {
std::cout << "Not found";
}
三、复合数据结构
8. 嵌套容器
用途:创建多维或复杂数据结构
常见组合:
cpp
// 二维数组
std::vector<std::vector<int>> matrix = {
{1, 2, 3},
{4, 5, 6}
};
// 字典列表
std::map<std::string, std::vector<double>> studentGrades = {
{"Alice", {95.5, 88.0}},
{"Bob", {78.5, 92.0}}
};
// 元组集合
std::set<std::tuple<int, int, int>> uniquePoints;
9. 结构体绑定
用途:组合相关数据字段
特点:
优于 std::pair/std::tuple 的语义清晰性
支持成员函数和自定义行为
cpp
struct Person {
std::string name;
int age;
std::vector<std::string> hobbies;
};
Person alice{"Alice", 30, {"Reading", "Hiking"}};
// C++17 结构化绑定
auto [name, age, hobbies] = alice;
四、数据结构对比指南
