Reputation: 29
How do I iterate through only part of a map in C++? My end goal is to have multiple threads iterate through their part of the map and compute some values. The map's type is std::map<std::string, std::vector<double> >
Upvotes: 1
Views: 698
Reputation: 126562
Here is a simple way of doing it in C++11:
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <future>
#include <iostream>
typedef std::map<std::string, std::vector<double>> map_type;
void do_work(map_type::iterator b, map_type::iterator e)
{
std::for_each(b, e, [] (map_type::value_type const& p)
{
std::for_each(p.second.begin(), p.second.end(), [] (double d)
{
/* Process an element of the vector... */
});
});
}
int main()
{
map_type m;
size_t s = m.size();
int quarter = s / 4;
auto i1 = m.begin();
auto i2 = std::next(i1, quarter);
auto i3 = std::next(i2, quarter);
auto i4 = std::next(i3, quarter);
auto i5 = m.end();
std::vector<std::future<void>> futures;
futures.push_back(std::async(do_work, i1, i2));
futures.push_back(std::async(do_work, i2, i3));
futures.push_back(std::async(do_work, i3, i4));
futures.push_back(std::async(do_work, i4, i5));
for (auto& f : futures) { f.wait(); }
}
Upvotes: 2
Reputation: 44288
If you want to split work by numbers evenly, then map probably not the best data structure. You would need to iterate over map and find iterators for particular positions. If you use container that provides random acces iterator like std::vector then you can just calculate iterators arithmetically. If you want to do that alphabetically, then you can do something like this:
typedef std::map<std::string,std::vector<double>> data;
void process( data::iterator beg, data::iterator end );
data dt;
{
auto task1 = std::async( process, dt.begin(), dt.lower_bound( "n" ) );
auto task2 = std::async( process, dt.lower_bound( "n" ), dt.end() );
}
assuming all strings are lowercase.
Upvotes: 1