[C++ STL] 对 equal_range 使用 范围for


引述

  使用

map<string,int> ma;
后可以创建一个map,因为map中所有键都是独一无二的,所以可以使用 [] 算符访问键值,如
ma["Hello"]=1;

  但是multimap访问键值就没那么方便了,multimap允许键重复,即同一键可能对应多个键值,因而multimap取消了 [] 算符.
通常已知键遍历multimap中的所有对应键值的方法有很多种,这是一种常用的方法

    multimap<string,int> mb;
    auto it=mb.equal_range("key");
    for(auto& i=it.first;i!=it.second;i++){
        cout<<i->second<<", ";
    }

可以看到这个方法显式地使用了迭代器.
  但说起遍历,最优美的遍历方法应当是使用 范围for , 范围for隐藏了迭代器


范围for

  cppreference 提到 范围for

for ( 范围声明 : 范围表达式 ) 循环语句
与下面这段代码等价

    {
        auto && __range = 范围表达式 ; 
        for (auto __begin = 首表达式, __end = 尾表达式; 
        __begin != __end; ++__begin) { 
            范围声明 = *__begin; 
            循环语句 
        } 
    } 

其中,__range , __begin 和 __end 仅用于说明内容,首表达式尾表达式 定义如下:

  • 范围表达式 是数组类型表达式,则 首表达式__range尾表达式(__range + __bound) ,其中 __bound 是数组的元素数目(若数组大小未知或拥有不完整类型,则程序不合法)
  • 范围表达式 是拥有名为 begin 以及 end 成员的类类型 C 的表达式(不管该成员的类型或可见性),则 首表达式__range.begin()尾表达式__range.end();
  • 否则, 首表达式begin(__range)1尾表达式end(__range) ,通过参数依赖查找寻找(不进行非 ADL 查找)
    范围表达式 返回临时量,则其生存期被延续到循环结尾,如同绑定到右值引用 __range 所示,但要注意 范围表达式 中任何临时量生存期都不被延长

  • 正文

      我希望这样子遍历 equal_range() 的结果

        for(auto& j:mb.equal_range("Hello")){
            out<<j.second<<", ";
        }

      注意到 equal_range 的返回值类型为 std::pair 也就是说当对其使用 范围for 时,会试图对其调用 begin()end() 以获取 __begin__end 来作为循环的控制条件.那么要实现如上方式,应当重载begin和end函数

        namespace std{
            template<typename Key,typename T>
            std::_Rb_tree_iterator<std::pair<Key,T>>&
                begin(std::pair<
                    std::_Rb_tree_iterator<std::pair<Key,T>>,
                    std::_Rb_tree_iterator<std::pair<Key,T>>
                >&i){
                return i.first;
            }
            template<typename Key,typename T>
            std::_Rb_tree_iterator<std::pair<Key,T>>&
                end(std::pair<
                    std::_Rb_tree_iterator<std::pair<Key,T>>,
                    std::_Rb_tree_iterator<std::pair<Key,T>>
                >&i){
                return i.second;
            }
        }

      搞定


    1. 编者注:值得一提,此处begin应当指std::begin,后文end亦同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值