zoukankan      html  css  js  c++  java
  • boost bimap 学习笔记 胜者,为王!!! 博客频道 CSDN.NET

    boost bimap 学习笔记 - 胜者,为王!!! - 博客频道 - CSDN.NET


    boost bimap 学习笔记


    分类:
    boost


    79人阅读
    评论(0)
    收藏
    举报

    bimap是boost中很重要的一个容器,可以进行双向的查找和替换,这样弥补了如果map和multimap需要找到data所对应的键值。循环遍历元素,才能找到相应的键值,再删除,最后替换的不足。

    但是boost的模板源编程又有着先天的缺点,就是编译错误不容易找到,编译时间有点长。但是如果长期使用boost,知道常见的错误,这个缺点还是可以慢慢克服的;虽然编译时间是有点长,但是比起自己一行一行自己写,还是说的过去的。

    下面是需要的一些头,如果只是简单使用bimap,仅引入#include 就可以了

     

    1. #include <iostream>  
    2. #include <map>  
    3. #include <boost/foreach.hpp>  
    4. #include <boost/typeof/typeof.hpp>  
    5. #include <boost/bimap.hpp>  
    6. #include <boost/bimap/set_of.hpp>  
    7. #include <boost/bimap/vector_of.hpp>  
    8. //#include <boost/bimap/tags/tagged.hpp>  
    9. usingnamespace boost::bimaps;  
    10. usingnamespace boost;  
    11. usingnamespace std;  

    首先写出一个打印bimap的工具函数,这个函数不仅可以打印bimap也可以打印map和multimap。

    这里用到了boost很常用的BOOST_AUTO和BOOST_FOREACH。个人比较倾向于我写的第一个实现。

    如果在程序灵活的使用boost的一些宏是可以很多的代码的。

    这里BOOST_FOREACH要比BOOST_AUTO要简明一些。但是试想如果不能用这两个的话,for循环的第一个参数应该写多长啊。

     

    1. //打印所有元素  
    2. template<classT>  
    3. voidprint_map(T &m)  
    4. {  
    5.     //方式一 比较喜欢用的方式  
    6.     BOOST_FOREACH(T::value_type v,m)  
    7.     {  
    8.         cout<<v.first<<" "<<v.second<<endl;  
    9.     }  
    10.     //方式二  
    11. //  for (BOOST_AUTO(pos,m.begin());pos!=m.end();++pos)  
    12. //  {  
    13. //      cout<<pos->first<<"--------"<<pos->second<<endl;  
    14. //  }  
    15. }  



    切记 简单bimap key/value 从两个个方向看必须都是唯一,虽然这个规则可以在后面改变

     

    1. typedefbimap<int,std::string> bm_t;  

    如果插入的值不唯一,将会显示第一次插入的结果。

    下面是左值重复插入测试

     

    1. intmain()  
    2. {  
    3.     std::map<int,int> test;  
    4.     //先创建  
    5.     test[1] = 2;  
    6.     //再修改  
    7.     test[1] = 4;  
    8.     cout<<test[1]<<endl;   //结果:4  
    9.    
    10.     //bimap左值重复测试  
    11.     bm_t col;  
    12.     col.left.insert(make_pair(5,"hello"));  
    13.     //虽然无效,但是可以插入  
    14.     col.left.insert(make_pair(5,"world"));  
    15.     //测试显示的是第一次插入的值  
    16.     BOOST_AUTO(iter,col.left.find(5));  
    17.     cout<<"left euql:"<<iter->second<<endl;   //结果:hello  
    18.    
    19.     //bimap右值重复测试  
    20.     col.right.insert(make_pair("hello",10));  
    21.     BOOST_AUTO(iter2,col.right.find("hello"));  
    22.     //对于右值查询,常量输出的方向应该相反,原first变seoond  
    23.     //测试同样显示的是第一次插入的值  
    24.     cout<<"right equal:"<<iter2->second<<endl;//结果:5  



    不能使用map的方式要访问简单的bimap,否则会造成

    编译错误,提示 error C2664: ‘boost::mpl::assertion_failed’ : cannot convert parameter 1 from ‘boost::mpl::failed

    对于模版源编程,熟悉一些错误对程序的纠错是非常有好处的

    虽然不能像关联数组一样使用operator[],但这个不是绝对的。

    可以使用来使用operator[]

     

    1. cout<<col.left[5]<<endl;  

    下面是右值重复插入测试

     
    1. typedefbm_t::value_type val;  
    2. //不使用左右视图,使用 value_type 插入元素  
    3. col.insert(val(50,"test_value_type"));  
    4.    
    5. typedefbm_t::left_value_type left_val;  
    6. //使用 left_value_type 插入元素  
    7. //同理 right_value_type 插入元素  
    8. col.left.insert(left_val(100,"left_value_type"));  
    9.    
    10. //传入一个左视图的结果集  
    11. print_map(col.left);  



    使用bimap库的一些类和方法可以使用可以使用operator[],而且可以不唯一key/value的bimap,但必须保证左视图为有序,右视图为随意访问类型。

     

    1. bimap<boost::bimaps::set_of<int>,boost::bimaps::vector_of<std::string> > bm_multi;  
    2. bm_multi.left.insert(make_pair(1,"111"));  
    3. bm_multi.left[2] = "222";  
    4. bm_multi.left[300] = "bimap";  
    5.    
    6. cout<<"use operator: "<<bm_multi.left[300]<<endl;  
    7. print_map(bm_multi.left);  
    8. //输出  
    9. //1 111  
    10. //2 222  
    11. //300 bimap  



    对于常见的访问类型,见下:

    set_of , multiset_of , unordered_set_of ,unordered_multiset_of : 可以做键值索引

    list_of ,vector_of ,unconstrained_set_of :不能用作键值索引

    关于这部分的具体内容可以参考《Boost程序库完全开发指南》P264

    关于 boost bimap 的tagged,使用boost tagged 给左右视图增加标签 这个功能在vs下不太稳定,但也可能是本人编译器的问题

     

    1. bimap<tagged<int,structid> ,tagged<std::string ,structname> > bm_tag_test;  
    2.  bm_tag_test.by<id>{}.insert(make_pair(1,"hello"));  
    3.  bm_tag_test.by<id>{}.insert(make_pair(2,"world"));  
    4.   
    5.  bm_tag_test.by<name>{}.insert(make_pair("test",3));  
    6.   
    7.  print_map(bm_tag_test.by<name>());  



    关于bimap的投射和替换,查找,修改功能,下次再给出详细说明。

  • 相关阅读:
    ExpandoObject与DynamicObject的使用
    ManualResetEvent 线程通信
    CancellationTokenSource 取消任务
    SQL Server 每日一题--老二解析
    说说 C# 8 using 新特性
    SQL Server 每日一题--老二
    C#中的坑--浮点类型
    开胃菜解析
    开胃菜
    快速入门 Arrow 日期处理库
  • 原文地址:https://www.cnblogs.com/lexus/p/2591654.html
Copyright © 2011-2022 走看看