Я уже спрашивал об этом в рассылке для буста, но мне было не совсем ясно, о моих намерениях это показалось. Возможно, я не совсем понимаю, как мне этого добиться.
Я хочу объединить несколько карт в Хану, см. Следующий пример кода:
constexpr auto m1 = hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key2"_s, hana::type_c<std::string>)
);
constexpr auto m2 = hana::make_map(
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
);
constexpr auto m3 = hana::make_map(
hana::make_pair("key6"_s, hana::type_c<std::string>),
hana::make_pair("key7"_s, hana::type_c<std::string>),
hana::make_pair("key8"_s, hana::type_c<std::string>)
);
Я уже получил ответ, как это сделать для двух карт:
constexpr auto result = hana::fold_left(m1, m2, hana::insert);
constexpr auto expected = hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key2"_s, hana::type_c<std::string>),
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
);
Когда я проверил документацию, я вижу, что fold_left принимает 2 или 3 аргумента.
Похоже, мне нужно что-то вроде:
fold_left (fold_left (m1, m3, hana :: insert), м2, hana :: insert);
template<typename Map...>
constexpr auto merge_multiple_maps(Map... args) {
// do something useful here...
}
Но я не уверен, что делать дальше, и у меня все еще не так много опыта в метапрограммировании …
С уважением, Маттис
Сначала определите merge2
следующее:
auto merge2 = [](auto&& m1, auto&& m2) {
return hana::fold_left(std::forward<decltype(m1)>(m1),
std::forward<decltype(m2)>(m2),
hana::insert);
};
Затем определите merge
как рекурсивное применение merge2
:
auto merge = [](auto&& m1, auto&& ...ms) {
return hana::fold_left(
hana::make_basic_tuple(std::forward<decltype(ms)>(ms)...),
std::forward<decltype(m1)>(m1),
merge2
);
};
Я не тестировал эту реализацию, но она должна дать вам идею. Если вам не нужна идеальная пересылка, вы можете отказаться от всех static_cast
; это просто для эффективности времени выполнения в случае, если вы храните типы, которые копируются, но дешевы для перемещения на вашей карте. Кроме того, вы не сможете использовать это в constexpr
контекст, потому что лямбды не могут появляться в константных выражениях. Это будет исправлено в C ++ 17, но сейчас вы можете легко реализовать функциональные объекты, эквивалентные этим лямбдам.
[Редактировать: Хана может реализовать это merge
функционировать в какой-то момент в будущем.]
[Редактировать: использовать std::forward
вместо static_cast
.]
Других решений пока нет …