Boost bimap find with multiset_of - c++

I have question with Boost::bimap and could not find answer from boost document.
using AToBBimap = boost::bimap< boost::bimaps::unordered_set_of<CString>, boost::bimaps::multiset_of<CString> >; //hashed bimap
using AToBBimapValueT = AToBBimap ::value_type;
AToBBimap bi_map;
bi_map.insert(AToBBimapValueT{"message1", "value"});
bi_map.insert(AToBBimapValueT{"message2", "value"});
bi_map.right.find("value");
QUESTION: with bi_map.right.find("value") looks like can only get iterator to {"message1", "value"}, is there possible to get a list of both matching like [{"message1", "value"}, {"message2", "value"}]?

The answer is equal_range("value"), like with std::multiset and std::multimap.
That member returns a pair of iterators, which is conveniently compatible with Boost's iterator-range factory, so you can use it:
for (auto p : boost::make_iterator_range(bi_map.right.equal_range("value")))
do something with p.second;

Related

Storing an boost multi_index index iterator

I have a boost::multi_index class which has multiple indexes.
If i want to store a normal iterator i can do
multi_index_table::const_iterator x_itr == my_table.find(x);
but if i try
multi_index_table::const_iterator x_itr == my_table.get_index(y).find(x) it complains that it's not the same type of iterator.
I'm fairly new to C++ and come from a java background, ideally i'd like some form of superclass which is able to store any type of iterator if that's possibile.
Any guidance will be much appreciated!
EDIT:
I'm basically looking to do something as such:
my_table.get_index(a).find(x);
x.erase<a>(x):
my_table.get_index(b).find(y);
x.erase<b>(y):
template<uint64_t Index>
template<typename Iterator>
Iterator erase(Iterator itr){
my_table.get_index<Index>().erase(itr)
}
With c++11 is rather easy. Just use:
auto x_itr = my_table.get_index(y).find(x)
The compiler will figure out the type of x_itr.

how get a random element boost unordered_map?

i using typedef boost::unordered_map. how to get a random element
v: c++ 03
code:
member_1.insert(std::make_pair(gg, M2_NEW CGGList(gg)));
typedef boost::unordered_map<CGG, CGGList*> Map1;
Map1 member_1;
You will not find an efficient method (wrong datastructure).
But you can always:
auto random_it = std::next(member1.begin(), my_random(member2.size()));
Where my_random would be implemented like rand()%n (bad) or using std::uniform_int_distribution<size_t> (much better).

std::map find() returning error

I am trying to compile the below code in VS2015. The first version of my std::map is compiling, but the seconds version does not compile. Please let me know what I am doing wrong here..
std::map<int, std::string> _p;
typedef std::pair<int, std::string> _q;
_p.insert(_q(0, "Football0"));
_p.insert(_q(1, "Football1"));
std::string str = _p[1]; //OK...compiles and executes, no error, str = "Football1" as expected
std::map<int, DataDictionary> _p1;
typedef std::pair<int, DataDictionary> _q1;
DataDictionary dd1;
dd1.i = 0;
dd1.version = "ver1";
_p1.insert(_q1(0, dd1));
DataDictionary dd2;
dd2.i = 0;
dd2.version = "ver2";
_p1.insert(_q1(1, dd2));
DataDictionary DD = _p1.find[1]; //error C3867: 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::find': non-standard syntax; use '&' to create a pointer to member
Even if I decide to change my std::map and use the following, I am getting the same error :
std::map<std::string, DataDictionary> _p1;
DataDictionary DD = _p1.find["1"]; //ERROR
I am trying to use map with the DataDictionary structure, and use _p1.find["1"] syntax to access the elements, as I am assuming that this approach will be faster than declaring iterator to the map, and then use find(). Please help. Thanks,
I am trying to use map with the DataDictionary structure, and use _p1.find["1"] syntax to access the elements
No, you are trying to use subscript operator on a member function:
find("1") would work.
find["1"] should not compile.
Consider using either _p1.find("1"), or _p1["1"]. The difference between them is that find returns a pair with a position in the map and a boolean flag an iterator (which may be past the end of the mapped sequence), and the subscript operator (["1"]) returns either a reference to the existing element, or it adds an element (if one is not found) and returns a reference to that.
To check if the map contains the key, use if(_p1.count("1")) instead.
I think you meant
_p1.find("1");
it returns an iterator to the found item.
use
std::map<std::string, DataDictionary>::iterator item = _p1.find("1");
or
in C++11 you can do
auto item = _p1.find("1");

Inserting into a std::Multimap of std::Map (C++)

If I have a std::multimap<int, std::map<int, MyClass>> myMultimap how to I insert a class object MyClassA into the map with value 1 at multimap value 2?
It looks like I can do myMultimap.at(2).insert(std::pair<1,MyClassA>); in c++11 but I am using c++98 due to a library regression/incomparability out of my control.
I've also tried
myMultimap[2].insert(
std::make_pair(
myMultimap[2].end(),
myClassA
)
);
which gives: error: no match for ‘operator[]’ (operand types are ‘std::multimap<int, std::map<int, ns_namespace::MyClassType> >’ and ‘int’)| for both of the [...]'s.
I don't want to do something like myMultimap.insert(std::make_pair(2,std::make_pair(1,MyClassA)))
because if I understand correctly, this would make a new map in the multimap rather than assigning the class object to the existing map within the multimap.
It is a two stage process:
Locate the position in the outer map where you want to do something to the inber map. If necessary, insert a new element.
Update the inner map withthe appropriatevalue.
I don't know why the outer map us a multimap (they are rarely useful) so the exampke just uses the first entry:
auto it = mymultimap.lower_bound(2);
if (it == mymultimap.end() || it->first != 2) {
it = mymultimap.insert(
std::make_pair(2, std::map<int, MyClass>())).first;
}
(*it)[1] = MyClassA;
(typed on a mobile device: there are probably typos but the overall approach should work).

Search for specific value in std::map [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Checking value exist in a std::map - C++
How to traverse a stl map/vector/list/etc?
Hello,
Is it possible to search for specific value in std::map, not knowing the key? I know I could iterate over whole map, and compare values, but it is possible to do using a function from std algorithms?
Well, you could use std::find_if :
int main()
{
typedef std::map<int, std::string> my_map;
my_map m;
m.insert(std::make_pair(0, "zero"));
m.insert(std::make_pair(1, "one"));
m.insert(std::make_pair(2, "two"));
const std::string s("one");
const my_map::const_iterator it = std::find_if(
m.begin(), m.end(), boost::bind(&my_map::value_type::second, _1) == s
);
}
But that's just slightly better than a hand-crafted loop : it's still O(n).
You could use Boost.Bimap if you want to index on values as well as keys. Without this or similar, this will have to be done by brute force (=> scan the map by hand).
Boost.Bimap is a bidirectional maps
library for C++. With Boost.Bimap you
can create associative containers in
which both types can be used as key.
Will this help? STL find_if
You need to have some sort of predicate, either a function pointer or an object with operator() implemented. Said predicate should take just one parameter.
There are (awkward) ways to do this using standard functions (e.g., std::find_if), but these still involve iterating over the whole map. Boost.Bimap will provide efficient indexing in both directions, and you can go even further with Boost.Multi-Index.