How to add the ordered unique index specifies in multi_index_container

梦想的初衷 提交于 2019-12-24 15:42:19

问题


I'm using boost:multi_index_container. following is the code

#include <string>
#include <boost/multi_index_container.hpp>
#include "boost/multi_index/global_fun.hpp"
#include "boost/multi_index/hashed_index.hpp"
#include <boost/multi_index/sequenced_index.hpp>
#include "boost/multi_index/mem_fun.hpp"
#include "boost/multi_index/member.hpp"
#include "boost/multi_index/ordered_index.hpp"
#include "boost/multi_index/indexed_by.hpp"

using namespace std;

class uri
{
public:
    string str;
    uri(string s) :str(s)
    {
    }
    string getUri(){ return str; }

};


struct UriWithBase
{
    UriWithBase(uri u1, uri u2) :link(u1), baseLink(u2){}
    uri link;
    uri baseLink;
};



int main()
{
    typedef boost::multi_index::multi_index_container <
        UriWithBase*,
        boost::multi_index::indexed_by <
        boost::multi_index::sequenced < >
        >
    > UriMultiIndex;

    UriMultiIndex m_uris;

    uri urib1("www.google.com");
    uri uri1("www.news.google.com");

    UriWithBase *ubptr = new UriWithBase(uri1, urib1);

    m_uris.push_back(ubptr);
    return 0;
}

Now I want to add a ordered unique index specifies in multi_index_container. This index is for unique order of elements in the container depends upon the first element of "UriWithBase" class i.e. uri link. I tried following but not worked. boost::multi_index::ordered_unique<

    boost::multi_index::tag<uris_by_uri>,
BOOST_MULTI_INDEX_CONST_MEM_FUN(UriWithBasePtr, const uri&, (*(UriWithBasePtr)).link)>

回答1:


There a few ways to add an ordered index:

  1. by using the ordered_unique specifier together with a custom comparator

    class uri
    {
    public:
        string str;
        uri(string s) :str(s)
        {
        }
        string getUri() const { return str; }
    };
    
    struct UriWithBase
    {
        UriWithBase(uri u1, uri u2) :link(u1), baseLink(u2){}
        uri link;
        uri baseLink;
    };
    
    struct CUriComparator {
        bool operator()(const uri &lh, const uri &rh) const {
            return lh.str < rh.str;
        }
    };
    
    struct uris_by_uri_and_crawl_state {};
    
    typedef boost::multi_index::multi_index_container <
        UriWithBase*,
        boost::multi_index::indexed_by <
          boost::multi_index::sequenced<>,
          boost::multi_index::ordered_unique <
            boost::multi_index::tag<uris_by_uri_and_crawl_state>,
            BOOST_MULTI_INDEX_MEMBER(UriWithBase, uri, link),
            CUriComparator
          >
        >
    > UriMultiIndex;
    
  2. by defining a compare operator of the uri class

    class uri
    {
    public:
        string str;
        uri(string s) :str(s)
        {
        }
        string getUri(){ return str; }
        bool operator < (const uri &rh) const    {
            return this->str < rh.str;
        }
    };
    
    struct UriWithBase
    {
        UriWithBase(uri u1, uri u2) :link(u1), baseLink(u2){}
        uri link;
        uri baseLink;
    };
    
    struct uris_by_uri_and_crawl_state {};
    
    typedef boost::multi_index::multi_index_container <
        UriWithBase*,
        boost::multi_index::indexed_by <
          boost::multi_index::sequenced<>,
            boost::multi_index::ordered_unique <
                boost::multi_index::tag<uris_by_uri_and_crawl_state>,
                BOOST_MULTI_INDEX_MEMBER(UriWithBase, uri, link)
            >
        >
    > UriMultiIndex;
    
  3. by declaring a method (UriWithBase::getLinkUri) in the UriWithBase class which returns the link's str member value.

    class uri
    {
    public:
        string str;
        uri(string s) :str(s)
        {
        }
        string getUri() const { return str; }
    };
    
    struct UriWithBase
    {
        UriWithBase(uri u1, uri u2) :link(u1), baseLink(u2){}
        uri link;
        uri baseLink;
    public:
        string getLinkUri(void) const {
            return link.getUri();
        }
    };
    
    struct uris_by_uri_and_crawl_state {};
    
    typedef boost::multi_index::multi_index_container <
        UriWithBase*,
        boost::multi_index::indexed_by <
            boost::multi_index::sequenced<>,
            boost::multi_index::ordered_unique <
                boost::multi_index::tag<uris_by_uri_and_crawl_state>,
                BOOST_MULTI_INDEX_CONST_MEM_FUN(UriWithBase, string, getLinkUri)
            >
        >
    > UriMultiIndex;
    



回答2:


class uri
{
public:
    string str;
    uri(string s) :str(s)
    {
    }

    // note we made this const
    string getUri() const { return str; }
};

inline bool operator<(const uri& x,const uri& y)
{
  return x.getUri()<y.getUri();
}

...

typedef boost::multi_index::multi_index_container <
    UriWithBase*,
    boost::multi_index::indexed_by <
    boost::multi_index::sequenced < >,
    boost::multi_index::ordered_unique<
        boost::multi_index::tag<uris_by_uri_and_crawl_state>,
        boost::multi_index::member<UriWithBase,uri,&UriWithBase::link>
    >
    >
> UriMultiIndex;


来源:https://stackoverflow.com/questions/29255152/how-to-add-the-ordered-unique-index-specifies-in-multi-index-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!