Фильтрация списка по типам с использованием boost :: hana

Я пытаюсь отфильтровать список с типами, но это не похоже на работу. Я уверен, что я делаю что-то не так, вот тест, который я создал, чтобы воспроизвести это:

#include <iostream>

#include <boost/hana.hpp>
#include <boost/hana/ext/std/tuple.hpp>

struct X {
};
struct Y {
};
struct Z {
};

int main(int argc, char **argv) {

namespace hana = boost::hana;

constexpr std::tuple<X, Y, Z> list;
constexpr std::tuple<X> filterlist;

auto t = hana::filter(list, [&](auto t) {
return hana::not_(hana::contains(filterlist, hana::decltype_(t)));
});

std::cout << "filtered list contains " << hana::size(t) << " items, expected 2 items" << std::endl;

return 0;
}

В основном то, что я хочу:
У меня есть список типов, и я хочу вернуть список с элементами, которых нет в списке фильтров. Так что в этом случае это должно быть std::tuple<Y, Z>,

Текущий вывод этой программы:
отфильтрованный список содержит 3 элемента, ожидается 2 элемента

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

1

Решение

Проблема в том, что вы проверяете ли тип (decltype_(X{}) == type<X>{}) находится в списке фильтров, который содержит реальные объекты, а не типы. Другими словами, это как если бы вы пытались сравнить std::type_info объект, представляющий некоторый тип T с объектом актуального типа T; это не имеет смысла семантически. Вместо этого вам нужно следующее:

#include <iostream>
#include <boost/hana.hpp>
#include <boost/hana/ext/std/tuple.hpp>
namespace hana = boost::hana;

struct X { };
struct Y { };
struct Z { };

int main(int argc, char **argv) {
constexpr std::tuple<X, Y, Z> list;
constexpr std::tuple<hana::type<X>> filterlist;
auto t = hana::remove_if(list, [&](auto t) {
return hana::contains(filterlist, hana::decltype_(t));
});

std::cout << "filtered list contains " << hana::size(t) << " items, expected 2 items" << std::endl;
}

При этом, если у вас уже есть filterlist кортеж, который есть в любом случае, для других целей, вы все равно можете использовать его для фильтрации:

#include <iostream>
#include <boost/hana.hpp>
#include <boost/hana/ext/std/tuple.hpp>
namespace hana = boost::hana;

struct X { };
struct Y { };
struct Z { };

int main(int argc, char **argv) {
constexpr std::tuple<X, Y, Z> list;
constexpr std::tuple<X> filterlist;
auto t = hana::remove_if(list, [&](auto t) {
return hana::any_of(filterlist, [&](auto u) {
return hana::decltype_(u) == hana::decltype_(t);
});
});

std::cout << "filtered list contains " << hana::size(t) << " items, expected 2 items" << std::endl;
}

Как последнее замечание, будьте осторожны с этими конструкциями, так как они O (n ^ 2) во время компиляции. Если вам нужен эффективный поиск, подумайте об использовании hana::set (реализация отстой прямо сейчас, но будет лучше, когда у меня будет больше времени).

3

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

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

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