Объединение нескольких карт

Я уже спрашивал об этом в рассылке для буста, но мне было не совсем ясно, о моих намерениях это показалось. Возможно, я не совсем понимаю, как мне этого добиться.

Я хочу объединить несколько карт в Хану, см. Следующий пример кода:

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...
}

Но я не уверен, что делать дальше, и у меня все еще не так много опыта в метапрограммировании …

С уважением, Маттис

4

Решение

Сначала определите 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.]

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector