I want to create a class which will have an std::tuple
with std::unordered_map
inside.
I want to create a method which will merge maps inside tuple.
#include <tuple>
#include <unordered_map>
template <typename ... Ts, std::size_t ... Is>
std::tuple<Ts...> merge_map (std::tuple<Ts...>& t1, std::tuple<Ts...> & t2, std::index_sequence<Is...> const &) {
return {
(std::get<Is>(t1).merge( std::get<Is>(t2)))...
};
}
template <class ...Ts>
struct MyContainer
{
std::tuple<Ts...> data;
void merge(MyContainer<Ts...>& other){
data = merge_map(data, other.data, std::make_index_sequence<sizeof...(Ts)>{});
}
};
int main()
{
using namespace std;
unordered_map<string, int> f = {{"zero", 0}, {"one", 1}};
MyContainer <unordered_map<string, int>> container1 = {.data = f};
unordered_map<string, int> s = {{"two", 2}, {"three", 3}};
MyContainer <unordered_map<string, int>> container2 = {.data = s};
container1.merge(container2);
}
But I can't compile this code.
I tried to create a simple example with un std::tuple
of int
's and make a sum of them and it worked. But I stuck on this more complex example.
Thank you for any suggestions.
The bigger problem I see is that std::unorderd_map<something...>::merge()
return void
.
So surely is wrong
return {
(std::get<Is>(t1).merge( std::get<Is>(t2)))...
};
I suggest to modify merge_map()
, using template folding, as follows
template <typename ... Ts, std::size_t ... Is>
std::tuple<Ts...> merge_map (std::tuple<Ts...> & t1,
std::tuple<Ts...> & t2,
std::index_sequence<Is...> const &) {
(std::get<Is>(t1).merge(std::get<Is>(t2)), ...);
return t1;
}
But also remember to include <string>
and that the {.data = f}
initialization syntax isn't C++17 (will be available starting from C++20, if I remember correctly).