添加到具有可变值的地图

Adding to a map with mutable values

本文关键字:地图 添加      更新时间:2023-10-16

假设我有一个名为 my_mapmap<string, vector<int>>,我想将42关联到密钥"foo"。来自Java,我希望必须做这样的事情

if (my_map.find("foo") != my_map.end()) {
    my_map["foo"].push_back(42);
} else {
    vector<int> my_vector;
    my_map["foo"] = my_vector;
    my_vector.push_back(42);
}

令我惊讶的是,我发现我可以做

my_map["foo"].push_back(42);

这是如何工作的?如果映射值的类型没有没有参数的构造函数,my_map["foo"]该怎么办?假设您想以不使用空构造函数的方式初始化所有值?在Java中,我可以做到

map.computeIfAbsent("foo", **some supplier of Vectors**).add(42);

C++有等价物吗?

my_map["foo"]默认构造一个新值(如果它尚不存在)。因此,如果值类型不是默认可构造的(即没有没有参数的构造函数),则会导致编译错误。然后,您必须执行以下操作:

my_map.emplace("foo", param).first->second.push_back(42);

如果emplace不存在,会从param构建您的值。

分段

构造函数可以从std::pair中提供更多参数:

my_map.emplace(
    std::piecewise_construct,
    std::forward_as_tuple("foo"),
    std::forward_as_tuple(param1, param2, param3)
).first->second.push_back(42);

你可以在这里阅读operator[]

如果 k 与容器中任何元素的键不匹配,则该函数将插入具有该键的新元素,并返回对其映射值的引用。请注意,这始终将容器大小增加 1,即使没有为元素分配映射值(元素是使用其默认构造函数构造的)。

如果mapped_type没有默认构造函数,则会收到编译错误。