2

I want to use multi index container of boost. To use it I tried following sample program to understand the insertion of elements in the container.

Following is my 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"

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.insert(ubptr);
  return 0;
}

However when I compiled the following it shows following error:

main.cc: In function `int main()':
main.cc:67: error: no matching function for call to `boost::multi_index::multi_index_container<UriWithBase*, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<UriWithBase*> >::insert(UriWithBase*&)'

../include/boost/multi_index/sequenced_index.hpp:304: note: candidates are: std::pair<boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type> >, bool> boost::multi_index::detail::sequenced_index<SuperMeta, TagList>::insert(boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type> >, const typename boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type>::value_type&) [with SuperMeta = boost::multi_index::detail::nth_layer<1, UriWithBase*, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<UriWithBase*> >, TagList = boost::mpl::vector0<mpl_::na>]
    ../include/boost/multi_index/sequenced_index.hpp:316: note:                 std::pair<boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type> >, bool> boost::multi_index::detail::sequenced_index<SuperMeta, TagList>::insert(boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type> >, boost::rv<typename boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type>::value_type>&) [with SuperMeta = boost::multi_index::detail::nth_layer<1, UriWithBase*, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<UriWithBase*> >, TagList = boost::mpl::vector0<mpl_::na>]
    ../include/boost/multi_index/sequenced_index.hpp:328: note:                 void boost::multi_index::detail::sequenced_index<SuperMeta, TagList>::insert(boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type> >, size_t, typename boost::call_traits<typename boost::multi_index::detail::sequenced_index_node<typename SuperMeta::type::node_type>::value_type>::param_type) [with SuperMeta = boost::multi_index::detail::nth_layer<1, UriWithBase*, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<UriWithBase*> >, TagList = boost::mpl::vector0<mpl_::na>]

Any pointer to resolve this error?

BSalunke
  • 11,499
  • 8
  • 34
  • 68

2 Answers2

1

You need an insertion hint here:

m_uris.insert(m_uris.end(), ubptr);

Oh, and here's a pointer: nullptr :)

sehe
  • 374,641
  • 47
  • 450
  • 633
1

The documentation says

The interface of sequenced indices is thus designed upon that of std::list; nearly every operation provided in the standard container is replicated here...

Thus the insert method requires two parameters. Using the push_back and push_front methods required one parameter - a reference to the value. Below is the compilable 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;
}
megabyte1024
  • 8,482
  • 4
  • 30
  • 44
  • @megabyte2014 thanks you for answer it worked very well. Could you please tell me how typedef should be declared to check insert status. I tried following but didn't worked typedef std::pair::type::iterator, bool> InsertStatus; – BSalunke Mar 25 '15 at 05:44
  • @BSalunke, It is `std::pair prRes = m_uris.push_back(ubptr);`, but I prefer `auto prRes = ....` – megabyte1024 Mar 25 '15 at 08:11
  • @megabyte2014 Thanks it worked, However I found one more problem :( Now I'm trying to add another index specifier in the multi index container that add the elements uniquely ordered for the first element of "UriWithBase" class i.e. link. How index specifier would be, I tried following but didn't worked boost::multi_index::ordered_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_CONST_MEM_FUN(UriWithBasePtr, const uri&, (*(UriWithBasePtr)).link)> – BSalunke Mar 25 '15 at 10:34
  • @BSalunke, My opinion is that your last question, does not relate to the title and it is better to create a new topic for it. BTW, I see a memory leak in the code, the `ubptr` object will be not deleted when the `m_uris` instance is deleted. A solution is to pass UriWithBase by value, i.e. `m_uris.push_back(UriWithBase(uri1, urib1));` or to wrap the `ubptr` pointer to a smart pointer. For sure in both cases the `UriMultiIndex` declaration will be changed. – megabyte1024 Mar 25 '15 at 10:57
  • added new thread for last question. http://stackoverflow.com/questions/29255152/how-to-add-the-ordered-unique-index-specifies-in-multi-index-container – BSalunke Mar 25 '15 at 12:04