STL 容器互相转换
必要的头文件
1
2
3
4
5
6
7
8
#include <vector>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm> // 用于 std::move, std::transform
#include <iterator> // 用于 std::inserter, std::back_inserter
vector 相关转换
vector move to set
1
2
3
4
std::vector<int> nums_v{0, 1, 2, 3};
std::unordered_set<int> nums_set;
std::move(nums_v.begin(), nums_v.end(), std::inserter(nums_set, nums_set.end()));
// 注意:move后原vector变为空
vector move to list
1
2
3
4
std::vector<int> nums_v{0, 1, 2, 3};
std::list<int> nums_list;
std::move(nums_v.begin(), nums_v.end(), std::back_inserter(nums_list));
// 注意:move后原vector变为空
vector copy to set
1
2
3
std::vector<int> nums_v{0, 1, 2, 3};
std::unordered_set<int> nums_set;
nums_set.insert(nums_v.begin(), nums_v.end());
vector copy to list
1
2
std::vector<int> nums_v{0, 1, 2, 3};
std::list<int> nums_list(nums_v.begin(), nums_v.end());
set 相关转换
set move to vector
1
2
3
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v(std::make_move_iterator(nums_set.begin()),
std::make_move_iterator(nums_set.end()));
set move to list
1
2
3
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::list<int> nums_list;
std::move(nums_set.begin(), nums_set.end(), std::back_inserter(nums_list));
注意:对于 set/unordered_set 这类元素为 const 的容器,move 语义和 copy 语义效果一致。
set copy to vector
1
2
3
4
5
6
7
8
9
10
11
12
13
// 方法1:使用构造函数
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v(nums_set.begin(), nums_set.end());
// 方法2:使用assign
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v;
nums_v.assign(nums_set.begin(), nums_set.end());
// 方法3:使用insert
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::vector<int> nums_v;
nums_v.insert(nums_v.end(), nums_set.begin(), nums_set.end());
set copy to list
1
2
std::unordered_set<int> nums_set{0, 1, 2, 3};
std::list<int> nums_list(nums_set.begin(), nums_set.end());
map 相关转换
map copy to vector of pairs
1
2
std::map<int, std::string> m{{1, "one"}, {2, "two"}};
std::vector<std::pair<int, std::string>> v(m.begin(), m.end());
map copy to vector of keys
1
2
3
4
std::map<int, std::string> m{{1, "one"}, {2, "two"}};
std::vector<int> keys;
std::transform(m.begin(), m.end(), std::back_inserter(keys),
[](const auto& pair) { return pair.first; });
map copy to vector of values
1
2
3
4
std::map<int, std::string> m{{1, "one"}, {2, "two"}};
std::vector<std::string> values;
std::transform(m.begin(), m.end(), std::back_inserter(values),
[](const auto& pair) { return pair.second; });
list 相关转换
list copy to vector
1
2
std::list<int> nums_list{0, 1, 2, 3};
std::vector<int> nums_v(nums_list.begin(), nums_list.end());
list copy to set
1
2
std::list<int> nums_list{0, 1, 2, 3};
std::unordered_set<int> nums_set(nums_list.begin(), nums_list.end());
注意事项
语义区别
- Move 语义:原容器中的元素会被移动,原容器变为空,性能更优
- Copy 语义:原容器保持不变,会产生额外的复制开销
容器特性
- 对于关联容器(如 set、map),转换到序列容器(如 vector、list)时需要注意元素顺序
- 对于 set/map 这类关联容器,元素类型为 const,move 语义和 copy 语义效果一致
- 对于 map 到 vector 的转换,通常需要指定转换的目标类型(key、value 或 pair)
性能考虑
- 大容器转换时优先使用 move 语义以避免不必要的复制
- 对于简单类型(如 int、double),move 和 copy 性能差异不大
- 对于复杂对象(如 string、自定义类),move 语义可以显著提升性能
使用技巧
- 使用
std::transform时,可以自定义转换逻辑,非常灵活 - 构造函数方式通常比先创建空容器再插入的方式效率更高