multimap学习之删除操作clear,erase,swap,extract,merge

本文介绍了C++标准库中multimap容器的删除操作,包括清除内容(clear)、擦除元素(erase)、交换内容(swap)、从另一容器释出结点(extract)及从另一容器接合结点(merge)。通过具体代码示例展示了这些操作的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇学习multimap删除相关的操作,具体的函数如下:

clear

清除内容
(公开成员函数)

erase

擦除元素
(公开成员函数)

swap

交换内容
(公开成员函数)

extract

(C++17)

从另一容器释出结点
(公开成员函数)

merge

(C++17)

从另一容器接合结点
(公开成员函数)
#include <iostream>
#include <map>
#include <string>

using namespace std;

void deleteOperator()
{
    //1.clear清除内容
    multimap<int, string> map1 = {{1,"draggonfruit"}, {2,"rambutan"}, {3,"guava"}};
    cout << "1 size = " << map1.size() << " empty = " << map1.empty() << endl;
    map1.clear();
    cout << "2 size = " << map1.size() << " empty = " << map1.empty() << endl;
    //2.erase擦除元素
    map1.insert({3, "sugercane"});
    map1.emplace(4, "grapefruit");
    map1.insert({5, "blackberry"});
    map1.insert({6, "kiwi"});
    map1.emplace(3, "gooseberry");
    map1.insert({7, "apple"});

    cout << "multimap元素如下:" << endl;
    for(auto val: map1)
    {
        cout << val.first << ": " << val.second << endl;
    }
    map1.erase(3);
    cout << "关键字删除元素" << endl;
    for(auto val: map1)
    {
        cout << val.first << ": " << val.second << endl;
    }
    cout << "迭代器删除元素" << endl;
    auto mapIt = map1.begin();
    map1.erase(mapIt);
    for(auto val: map1)
    {
        cout << val.first << ": " << val.second << endl;
    }
    cout << "范围删除元素" << endl;
    auto startIter = map1.begin();
    auto endIter = ++startIter;
    ++endIter;
    ++endIter;
    map1.erase(startIter, endIter);
    for(auto val: map1)
    {
        cout << val.first << ": " << val.second << endl;
    }
    auto mapIter2 = map1.begin();
    while(mapIter2 != map1.end())
    {
        cout << mapIter2->first << ": " << mapIter2->second << endl;
        ++mapIter2;
    }

    //3.swap交换内容
    multimap<int, string> map2 = {{11,"fig"}, {12,"lemon"}, {13,"olive"}};;
    auto map2Iter = map2.begin();
    while(map2Iter != map2.end())
    {
        cout << map2Iter->first << ": " << map2Iter->second << endl;
        ++map2Iter;
    }
    map2.swap(map1);
    cout << "map1: " << endl;
    for(auto map1iter = map1.begin(); map1iter != map1.end(); ++map1iter)
    {
        cout << map1iter->first << ": " << map1iter->second << endl;
    }

    cout << "map2: " << endl;
    for(auto map2iter = map2.begin(); map2iter != map2.end(); ++map2iter)
    {
        cout << map2iter->first << ": " << map2iter->second << endl;
    }

    //4.extract从另一容器释出结点   C++17 提取
    cout << "map3: " << endl;
    multimap<int, string> map3{{1,"apple"}, {5,"pear"}, {5,"peach"}, {3,"grape"}};
    auto nh = map3.extract(5);//参数key
    nh.key() = 2;
    map3.insert(move(nh));
    for(auto map3iter = map3.begin(); map3iter != map3.end(); ++map3iter)
    {
        cout << map3iter->first << ": " << map3iter->second << endl;
    }
    cout << "map3.size = " << map3.size() << endl;
    //5.merge从另一容器接合结点   C++17
    multimap<int, string> map4{{2, "durian"}, {5, "mango"}};;
    multimap<int, string> map5{{1, "strawberry"}, {5, "banana"}, {8, "orange"}};
    map5.merge(map4);//相同的关键字也会合并,例如5
    cout << "map4: " << endl;
    for(auto const &value: map4)
    {
        cout << value.first << ": " << value.second << endl;
    }

    cout << "map5: " << endl;
    for(auto const &value: map5)
    {
        cout << value.first << ": " << value.second << endl;
    }
}

int main()
{
    deleteOperator();
    cout << "Hello, world!" << endl;
    return 0;
}

运行结果:

 

参考:

https://zh.cppreference.com/w/cpp/container/multimap

<think>好的,我现在需要回答用户关于C++ multimap为何没有重载operator[]的问题。首先,我得回忆一下C++标准库中map和multimap的区别。记得map中的每个键是唯一的,而multimap允许键重复。operator[]在map中用于通过键访问对应的值,如果键不存在,则会插入一个新的元素。那为什么multimap不提供这个操作呢? 可能的原因之一是multimap允许同一个键对应多个值,所以operator[]在这里会有歧义。比如,如果用户用[]访问一个键,此时应该返回哪个值呢?因为可能有多个值关联到同一个键,无法确定唯一的返回值,所以标准委员会可能认为这样的操作不符合语义明确的要求,因此没有重载operator[]。 另外,operator[]在map中还有插入元素的功能。但在multimap中,由于键可以重复,插入元素时不需要检查键是否存在,直接插入即可。而operator[]通常需要返回一个可以修改的引用,这在multimap的情况下无法保证,因为可能有多个元素,无法确定引用哪一个。这可能导致未定义行为或者设计上的复杂性,所以选择不提供这个操作符。 还需要考虑标准库的设计哲学,即提供明确且无歧义的接口。multimap的接口设计可能更倾向于使用insert、find、equal_range等方法,这些方法能更明确地处理多键的情况。例如,find返回一个迭代器,但需要用户自己处理多个值的情况,而equal_range可以返回一个区间,允许遍历所有相同键的元素。这样的设计避免了operator[]可能带来的歧义和使用上的困惑。 此外,参考引用中的内容,比如C++03和C++11的一些特性变化,可能涉及到类型推导和迭代器的设计。虽然用户提供的引用主要讨论的是类型大小和迭代器类型推导,但可以联想到迭代器在multimap中的行为类似于指针,而multimap的迭代器需要处理多个相同键的情况,这也可能导致operator[]难以设计。 总结起来,主要原因应该是multimap允许多个相同键的存在,导致operator[]无法明确返回哪个值的引用,且插入行为与map不同,所以标准库选择不重载该操作符,转而提供其他更合适的成员函数来处理多键的情况。</think>C++中`multimap`未重载`operator[]`的原因与其设计目标及底层特性密切相关,主要基于以下几个关键考量: 1. **键值对的多重性矛盾** `multimap`允许存在多个相同键(key)的元素,而`operator[]`在`map`中的语义是*返回指定键对应的唯一值*。当键对应多个值时,无法确定应返回哪个值,导致语义二义性。例如: ```cpp multimap<string, int> m {{"apple", 5}, {"apple", 7}}; int val = m["apple"]; // 应返回5还是7?无法确定 ``` 2. **插入行为的不可控性** 在`map`中,`operator[]`会在键不存在时自动插入默认值(如`map<string, int> m; m["new_key"]++;`)。但`multimap`的插入不需要检查键是否存在,直接调用`insert`即可: ```cpp m.insert({"new_key", 1}); // 明确插入操作 ``` 若`operator[]`实现自动插入,会破坏`multimap`强调的显式插入语义[^1]。 3. **接口安全性的权衡** `operator[]`要求返回可修改的引用,但在`multimap`中,同一键可能对应多个值,直接修改可能引发数据一致性风险。标准库更推荐通过迭代器操作: ```cpp auto range = m.equal_range("apple"); for (auto it = range.first; it != range.second; ++it) { it->second = 10; // 明确修改具体元素 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值