3
#include <iostream>
using namespace std;

#include <typeinfo>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/optional.hpp>

using boost::multi_index_container;
namespace mi = boost::multi_index;

class employee
{
    public :

    std::string name;

    boost::optional<unsigned int> id;

    unsigned int presence;
};

struct ByName{};

struct ById{};


int main() 
{
    typedef boost::multi_index_container<
      employee,
      mi::indexed_by<
    // sort by less<string> on name
    mi::ordered_unique<mi::tag<ByName>,mi::member<employee,std::string,&employee::name>>,
    mi::ordered_unique<mi::tag<ById>,mi::member<employee,boost::optional<unsigned int>,&employee::id>>
      > 
    >employee_set;

    employee_set empDataBase;

    class employee emp1, emp2, emp3;

    std::string name("Mahesh");
    emp1.name = name;
    emp1.presence = true;
    emp1.id = 1000;

    std::string name1("Rajesh");
    emp2.name = name1;
    emp2.presence = true;


    std::string name3("Piku");
    emp3.name = name3;
    emp3.presence = true;
    emp3.id = 2000;

    bool result = empDataBase.insert(emp1).second;
    printf("result 1 is %d\n", result);

    result = empDataBase.insert(emp2).second;
    printf("result 2 is %d\n", result);

    result = empDataBase.insert(emp3).second;
    printf("result 3 is %d\n", result);

    /* Get the value from the multi-index using first and second ordered index */
    employee_set::iterator i = empDataBase.get<ByName>().find(name1);

    printf ("name - %s, presence - %d, Id intialized ? %d\n", (*i).name.c_str(), (*i).presence, (*i).id.is_initialized());


    employee_set::iterator ii = empDataBase.get<ById>().find(2000);

    printf ("name - %s, presence - %d, id Value %d\n", (*ii).name.c_str(), (*ii).presence, (*ii).id.get());

    empDataBase.erase(i);
    empDataBase.erase(ii);

    /* Get the value from the multi-index using first and second ordered index */
    i = empDataBase.get<ByName>().find(name1);

    printf ("name - %s, presence - %d, Id intialized ? %d\n", (*i).name.c_str(), (*i).presence, (*i).id.is_initialized());

    return 0;

}

employee_set::iterator ii gives me following error. How should i define the iterator ?

prog.cpp: In function 'int main()': prog.cpp:76:63: error: conversion from 'boost::multi_index::detail::ordered_index, &employee::id>, std::less >, boost::multi_index::detail::nth_layer<2, employee, boost::multi_index::indexed_by, boost::multi_index::member, &employee::name> >, boost::multi_index::ordered_unique, boost::multi_index::member, &employee::id> > >, std::allocator >, boost::mpl::v_item, 0>, boost::multi_index::detail::ordered_unique_tag>::iterator {aka boost::multi_index::detail::bidir_node_iterator > > >}' to non-scalar type 'boost::multi_index::multi_index_container, boost::multi_index::member, &employee::name> >, boost::multi_index::ordered_unique, boost::multi_index::member, &employee::id> > > >::iterator {aka boost::multi_index::detail::bidir_node_iterator > > > >}' requested employee_set::iterator ii = empDataBase.get().find(2000);

Praetorian
  • 106,671
  • 19
  • 240
  • 328
mahesh gs
  • 61
  • 2

1 Answers1

4

Each index of a multi_index_container has its own iterator type which can't be freely interchanged with those of other indices. So, you have to write something like

employee_set::index<ById>::type::iterator ii = empDataBase.get<ById>().find(2000);

or, if using C++11, simply

auto ii = empDataBase.get<ById>().find(2000);

in the understanding that the type of ii is not the same as that of, say, i. Similarly, the line

empDataBase.erase(ii);

won't work because ii is an iterator of the ById index, whereas empDataBase, whitout further qualification, refers to index #0 (ByName). So you have to write

empDataBase.get<ById>().erase(ii);

or resort to iterator projection.

Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20