Search code examples
c++boostboost-bimap

Access value with key in bimap


I am trying to get a value accessed by its key. I have a minimal example that I tried so far, and works fine only for left side access.

#include <string>
#include <iostream>
#include <utility>
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>

namespace bimaps = boost::bimaps;
typedef boost::bimap<bimaps::set_of<unsigned long int>,
        bimaps::multiset_of<std::pair<unsigned long int, unsigned long int> > > bimap_reference;
typedef bimap_reference::value_type position;
bimap_reference numbers;

int main()
{
    numbers.insert(position(123456, std::make_pair(100000,50000)));
    numbers.insert(position(234567, std::make_pair(200000,80000)));
    numbers.insert(position(345678, std::make_pair(300000,10000)));
    numbers.insert(position(456789 ,std::make_pair(100000,60000)));


    auto it = numbers.left.at(123456);
    std::cout<<"numbers:"<<it.first<<"<->"<<it.second<<std::endl;
    return 0;
}

And when I tried to look from the right by using a paired key to access a value, and as a trail I tried the following.

auto itt = numbers.right.at({100000,50000});
auto itt = numbers.right.at(std::make_pair(100000,50000));
std::cout<<"from right: "<<itt.first<<std::endl;

> error: ‘boost::bimaps::bimap, boost::bimaps::multiset_of > >::right_map {aka class boost::bimaps::views::multimap_view, boost::bimaps::multiset_of >, mpl_::na, mpl_::na, mpl_::na> >}’ has no member named ‘at’ auto itt = numbers.right.at({100000,50000});

The above lines are not working. I also would like to know if it is possible to get access by using only one element of paired key something like

auto itt = numbers.right.at({50000});

Solution

  • The documentation already contains all what you need to diagnose the problem.

    First of all, note that the type of your right view is multiset_of.
    As you can see here, multiset_of's equivalent container is std::multimap and the latter has not the member function at.
    Because of that, you cannot invoke at on a multiset_of, that is what you get when accessing the right view of the map through .right.
    The error is also pretty clear indeed.

    You can use find to get out an iterator to the object you are looking for:

    auto itt = numbers.right.find(std::make_pair(100000,50000));
    std::cout<<"from right: "<<itt->first.first <<std::endl;    
    

    Well, checking it against .end() would probably be a good idea.

    And no, you cannot search with half a key as a parameter. If you want to do things like that you should rather use something like a map where the keys are the first elements of your pairs and the values are lists of those pairs or some other data structure that is well suited for your real problem.
    Definitely (almost) unfeasible with a bimap, it doesn't worth it.