Multiset(下)——Boost中的bimap和multiset_of

  理解了std::multiset之后,理解boost::bimap和boost::bimap::multiset_of就不在话下了。不过在此之前,最好还是先了解下std::multimap:

 

  http://blog.csdn.net/believefym/article/details/1627874

  http://www.cplusplus.com/reference/map/multimap/

 

  当bimap和multiset_of结合使用时,取得的效果其实就类似multimap。当我们定义了一个双向映射类型bimap<X, Y>时,该映射中的左键X和右键Y都必须是唯一的。如果把映射类型改为bimap< multiset_of<X>, Y >,那么左键X就允许出现重复值,左键集合就是一个多重集合(multiset)。如果再把类型改为bimap< multiset_of<X>, multiset_of<Y> >那么右键Y也允许出现重复值了。

 

  下面举一个例子。假设我们正在做一个商店的查询系统,这个系统的用户会频繁地查询某家商店开在了哪个城市,又会频繁地查询某个城市有什么商店。对此一个很好的解决方案是在内存中维护一个商店和城市之间的bimap作为查询缓存。但是一个城市可能会有多家商店;有的商店又可能是连锁店,会出现在多个城市。因此我们需要multiset_of。完整的类型定义如下:

 

struct shopname {};
struct location {};

typedef bimap<
    multiset_of< tagged< std::string, shopname > >,
    multiset_of< tagged< std::string, location > >
> ShopMap;

typedef ShopMap::value_type Shop;

 

  作为示例,我们先往bimap中插入几条记录:

 

ShopMap shopMap;

shopMap.insert( Shop( "7-11",     "Beijing" ) );
shopMap.insert( Shop( "Wallmart", "Beijing" ) );
shopMap.insert( Shop( "7-11",     "Shanghai" ) );
shopMap.insert( Shop( "Wallmart", "Shanghai" ) );
shopMap.insert( Shop( "MyShop",   "Shanghai" ) );

 

  如果我们想知道沃尔玛开在了哪些城市:

 

const auto wallmartRange = shopMap.by<shopname>().equal_range("Wallmart");
for (auto iter = wallmartRange.first; wallmartRange.second != iter; ++iter)
{
    std::cout << iter->get<location>() << std::endl;
}

 

  如果我们想知道上海有几家商店:

 

shopMap.by<location>().count("Shanghai")

 

  完整的示例代码:

 

#include <iostream>
#include <string>

#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>

using namespace boost::bimaps;

struct shopname {};
struct location {};

typedef bimap<
    multiset_of< tagged< std::string, shopname > >,
    multiset_of< tagged< std::string, location > >
> ShopMap;

typedef ShopMap::value_type Shop;

int main()
{
    ShopMap shopMap;

    shopMap.insert( Shop( "7-11",     "Beijing" ) );
    shopMap.insert( Shop( "Wallmart", "Beijing" ) );
    shopMap.insert( Shop( "7-11",     "Shanghai" ) );
    shopMap.insert( Shop( "Wallmart", "Shanghai" ) );
    shopMap.insert( Shop( "MyShop",   "Shanghai" ) );

    std::cout << "Wallmart is opened in: " << std::endl;
    const auto wallmartRange = shopMap.by<shopname>().equal_range("Wallmart");
    for (auto iter = wallmartRange.first; wallmartRange.second != iter; ++iter)
    {
        std::cout << iter->get<location>() << std::endl;
    }
    std::cout << std::endl;

    std::cout << "Shanghai has " << shopMap.by<location>().count("Shanghai") << " shop(s)." << std::endl;

    return 0;
}


 

你可能感兴趣的:(Multiset(下)——Boost中的bimap和multiset_of)