roy.atlas
roy.atlas

Reputation: 421

How to find all elements with the same key value in a boost::multi_index_container

After building a boost multi_index_container I would like to visit all elements with the same key value. The following code gives the basic idea of what is expected:

#include <iostream>
#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>


using namespace std;
using namespace :: boost;
using namespace ::boost::multi_index;


struct name{};
struct id{};
struct employee
{
  int         id;
  std::string name;

  employee(int id,const std::string& name):id(id),name(name){}
  
};


// define a multiply indexed set with indices by id and name
typedef multi_index_container<
  employee,
  indexed_by<

    ordered_unique<tag<id>,member<employee,int,&employee::id>>,
    
    ordered_non_unique<tag<name>,member<employee,std::string,&employee::name> >
  > 
> employee_set;


int main() {
  employee_set employee_collection ;
  employee_collection.insert(employee(1,"Tony"));
  employee_collection.insert(employee(2,"Bob"));
  employee_collection.insert(employee(4,"Thomas"));
  employee_collection.insert(employee(5,"Richard"));
  employee_collection.insert(employee(6,"Bill"));
  employee_collection.insert(employee(7,"Robert"));
  employee_collection.insert(employee(8,"Bob"));

  
  typedef employee_set::index<name>::type employee_set_by_name;
  employee_set_by_name::iterator it  =
    employee_collection.get<name>().find("Bob"); // I want a collection of "Bob"s
  cout << (*it).id<< endl;

  /* This won't compile
  for(it = employee_collection.get<name>().find("Bob").begin();
      it != employee_collection.get<name>().find("Bob").end(); ++it){
    cout << (*it).id << endl;
    }*/

  return 0 ;
}
// References:
// Boost documentation

The above code finds the first Bob ordered in an alphabetic way while two Bobs are in interest.

Upvotes: 2

Views: 211

Answers (1)

Use equal_range:

typedef employee_set::index<name>::type employee_set_by_name;
std::pair<
  employee_set_by_name::iterator, 
  employee_set_by_name::iterator > p = employee_collection.get<name>().equal_range("Bob");

while(p.first != p.second) {
  cout << (*p.first).id << endl;
  ++p.first;
}

Upvotes: 1

Related Questions