Можно ли использовать карту Boost Fusion в обратном порядке, иначе ключ 567, значение типа?

Я бы хотел
значение для типа карты, и из того, что я вижу, Boost Fusion использует карту, которая использует пару, где тип всегда является первым членом (так что это ключ на карте)?

map_type m(
fusion::make_pair<int>('X')
, fusion::make_pair<double>("Men"));

Можно ли сделать значение (например, «X» в примере выше) ключом и ввести значение?
Если нет, я могу, по крайней мере, сделать фильтр на основе значения (это медленно, поэтому было бы неплохо узнать, могу ли я отсортировать вектор слияния на основе второго параметра и использовать для этого двоичный_поиск (снова с пользовательским компаратором, который просматривает значение, а не ключ) ,

2

Решение

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

Вам нужно перечислить типы во время компиляции, а затем связать тип времени выполнения со смещением в указанном списке. tuple уже отображает индексы для типов для вас.

Ты не можешь вернуть тип, но вместо этого вы можете вызвать переданный в шаблон functo с типом.

Однако, прежде чем идти по этому пути, вы должны иметь в виду конкретную цель и посмотреть, если; Есть менее запутанные способы ее решения.

1

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

Интересный вопрос. Обычно это не сработает, потому что на самом деле не существует способа представления типа во время выполнения с такой же семантикой, известной во время компиляции, например, нет виртуальных конструкторов (см. Страницу Moder C ++ Design 200, параграф 8.2). Но Fusion поддерживает for_each который итерацию во время компиляции по последовательности и вызывает объект функции времени выполнения. Теперь этот функциональный объект может быть универсальным фильтром, пересылающим вызов другому универсальному функциональному объекту, если его универсальный предикат возвращает true.

Теперь ее код:

#include <boost/fusion/container/map.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>

#include <string>
#include <iostream>
#include <typeinfo>

using namespace boost::fusion;template<class Pred,class Fun>
struct filter {
Pred pred_;
Fun& fun_;

filter(Pred p, Fun& f)
: pred_(p)
, fun_(f)
{}

template<class Pair>
void operator()(Pair& pair) const {
if (pred_(pair.second))
fun_(pair);
}
};

template<class Pred,class Fun>
filter<Pred,Fun> make_filter(Pred p, Fun& f) {
return filter<Pred,Fun>(p, f);
}

typedef map
< pair<int, char>
, pair<double, std::string>
> map_type;

struct fun {
template<class First,class Second>
void operator()(pair<First,Second>& t) const {
std::cout
<< typeid(First).name() << std::endl
<< typeid(Second).name() << ":" << t.second << std::endl;
}
};

struct mypred {
template<class T>
bool operator()(T const&) const {
return false;
}

bool operator()(char c) const {
return c=='X';
}
};

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

map_type m(
make_pair<int>('X'),
make_pair<double>("Men")
);

for_each(m, make_filter(mypred(),fun()));

return 0;
}

Класс фильтра хранит предикат и функциональный объект. Если предикат возвращает true на pair.second В твоем случае 'X' он вызывает объект функции. make_filter маленький помощник для создания фильтра. Теперь осталось две части кода: мой особый предикат mypred, которые только принимают char (вы должны иметь дело с перегрузкой для более общих реализаций) и мой объект функции fun который выводит информацию о типе и значение. В основном for_each называется с filter, Обратите внимание: фильтр предназначен для получения объекта функции по ссылке, чтобы он мог передавать аргументы и результат. В конце концов, это вариация специальное посещение. Если вы беспокоитесь о скорости, вы должны знать, что почти все может быть встроено. В этом конкретном примере сравниваются только символы, для всех других типов результат false и никакая функция не вызывается. Конечно, есть много возможностей для улучшения, но у меня нет времени, чтобы сделать это сейчас. Возможно, есть лучшие способы реализовать это, но это была моя первая программа с boost.fusion :-).

1

По вопросам рекламы [email protected]