C++中初始化std::map有多种方式,最推荐的是C++11列表初始化,如std::map<std::string, int> ages = {{"Alice", 30}, {"Bob", 25}};,因其可读性高且简洁。此外还可使用insert()、emplace()、operator[]、范围构造、拷贝或移动构造等方式,每种方法在性能和语义上各有差异,需根据是否需要高效构造、键是否存在、数据来源等场景选择合适方法;自定义比较器和分配器可进一步控制排序和内存管理行为。

在C++中初始化
std::map
初始化
std::map
首先,最直接也最基础的,就是默认构造一个空的map
std::map<std::string, int> myMap;
C++11 列表初始化: 这是现代C++中我个人最常用也最推荐的方式,简洁明了,可读性极高。
std::map<std::string, int> ages = {{"Alice", 30}, {"Bob", 25}, {"Charlie", 35}};std::map<std::string, int> scores;
scores = {{"Math", 95}, {"Science", 88}};std::initializer_list
insert
使用insert()
insert
std::pair
myMap.insert(std::pair<std::string, int>("David", 40));std::make_pair
myMap.insert(std::make_pair("Eve", 28));std::pair
myMap.insert({"Frank", 33});emplace()
emplace
map
myMap.emplace("Grace", 22);emplace
insert
使用operator[]
myMap["Heidi"] = 29;
"Heidi"
operator[]
0
29
范围构造(Range Construction): 如果你有一系列键值对,可以利用迭代器范围来初始化
map
std::vector<std::pair<Key, Value>>
std::vector<std::pair<std::string, int>> initial_data = {{"Ivan", 45}, {"Judy", 38}};std::map<std::string, int> team_members(initial_data.begin(), initial_data.end());
拷贝构造与移动构造: 你可以用一个已有的
map
map
std::map<std::string, int> existingMap = {{"Kate", 50}};std::map<std::string, int> newMapCopy(existingMap); // 拷贝构造
std::map<std::string, int> newMapMove(std::move(existingMap)); // 移动构造 (C++11起)
我个人觉得,自从C++11引入列表初始化后,
map
map
insert
比如,以前我可能需要这样写:
立即学习“C++免费学习笔记(深入)”;
std::map<std::string, int> config;
config.insert(std::make_pair("timeout", 3000));
config.insert(std::make_pair("retries", 5));
config.insert(std::make_pair("max_connections", 100));现在,有了列表初始化,代码就成了这样:
std::map<std::string, int> config = {
{"timeout", 3000},
{"retries", 5},
{"max_connections", 100}
};是不是简洁很多?它的内部机制其实是利用了
std::initializer_list<std::pair<const Key, Value>>
map
insert
map
这种方式的优点在于它的声明式风格,你不是在“执行”一系列操作来构建
map
map
insert()
operator[]
在填充
map
insert()
operator[]
insert()
map
map
std::pair<iterator, bool>
bool
false
insert
std::map<std::string, int> scores;
auto [it1, inserted1] = scores.insert({"Math", 90}); // inserted1 == true
auto [it2, inserted2] = scores.insert({"Math", 95}); // inserted2 == false, value remains 90emplace()
insert()
map
而
operator[]
myMap[key] = value;
key
map
key
Value
key
Value
key
Value
性能考量:
insert()
emplace()
emplace
std::pair
insert
std::pair
operator[]
operator[]
Value
Value
operator[]
insert
emplace
operator[]
myMap[key] = newValue;
陷阱: 我遇到过不少新手,甚至包括我自己,在不经意间用
operator[]
std::map<std::string, int> data;
// ... 填充了一些数据 ...
if (data["non_existent_key"] > 0) { // 这里!"non_existent_key"会被插入,值为0
// ...
}仅仅访问
data["non_existent_key"]
map
int
0
map
map::count()
map::find()
map::contains()
总结一下,如果你需要确保键的唯一性且不希望覆盖现有值,或者希望在插入时直接构造复杂对象,
insert()
emplace()
operator[]
有时候,你的数据并不是以
std::map
std::vector
std::list
map
map
map
这种初始化方式的核心在于提供一对迭代器,它们定义了一个范围,
map
std::pair<const Key, Value>
举个例子,假设你从文件读取了一系列用户ID和名称,存储在一个
std::vector
struct UserInfo {
int id;
std::string name;
};
std::vector<UserInfo> users = {
{101, "Alice"},
{102, "Bob"},
{103, "Charlie"}
};如果你想以ID为键,名称为值来构建一个
map
users.begin(), users.end()
UserInfo
std::pair<int, std::string>
std::map::try_emplace
std::transform
更常见的场景是,你已经有了一个
std::vector<std::pair<Key, Value>>
std::vector<std::pair<int, std::string>> employee_data = {
{1001, "John Doe"},
{1002, "Jane Smith"},
{1003, "Peter Jones"}
};
// 直接从vector初始化map
std::map<int, std::string> employees(employee_data.begin(), employee_data.end());
// 打印验证
for (const auto& [id, name] : employees) {
// std::cout << "ID: " << id << ", Name: " << name << std::endl;
}这种方式的优势在于它的简洁性和效率。
map
vector
insert
它在处理批量数据导入、将其他数据结构转换为
map
map
std::map
Compare
Allocator
map
自定义比较器(Compare
std::map
std::less<Key>
map
operator<
这个比较器必须是一个可调用对象(函数对象、lambda表达式或函数指针),它接受两个
const Key&
bool
// 示例:一个字符串的自定义比较器,忽略大小写
struct IgnoreCaseCompare {
bool operator()(const std::string& a, const std::string& b) const {
return std::lexicographical_compare(
a.begin(), a.end(),
b.begin(), b.end(),
[](char ca, char cb){ return std::tolower(ca) < std::tolower(cb); }
);
}
};
// 使用自定义比较器初始化map
std::map<std::string, int, IgnoreCaseCompare> caseInsensitiveMap = {
{"Apple", 1},
{"apple", 2}, // 这个会被认为是重复键,因为比较器认为 "Apple" 和 "apple" 是相等的
{"Banana", 3}
};
// caseInsensitiveMap["apple"] 会访问到 "Apple" 的值
// caseInsensitiveMap["APPLE"] 也会访问到 "Apple" 的值在初始化
map
insert
operator[]
map
自定义分配器(Allocator
std::map
std::allocator<std::pair<const Key, Value>>
// 假设你有一个自定义的MyAllocator
// #include "MyAllocator.h" // 假设MyAllocator定义在这里
std::map<std::string, int, std::less<std::string>, MyAllocator<std::pair<const std::string, int>>> myMapWithCustomAlloc;
// 你仍然可以用列表初始化填充数据
myMapWithCustomAlloc = {
{"One", 1},
{"Two", 2}
};自定义分配器通常是更高级的话题,对于大多数日常编程任务来说,默认的
std::allocator
map
map
这算是稍微进阶一点的话题了,但如果你想让
map
map
以上就是如何在C++中初始化一个map_C++ map初始化方法大全的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号