Получение индекса boost::fusion::vector из boost::mpl::vector
Я начал играть с библиотекой boost fusion и mpl и столкнулся с довольно простой проблемой.
Я объявил следующие типы:
typedef boost::mpl::vector<char, int, long> TypeVector;
typedef boost::fusion::vector<char, int, long> FusionVector_t;
Теперь я хотел написать функцию, которая получает значение от FusionVector.
template<size_t N typename T>
T getValue(FusionVector_t fvec)
{
return boost::fusion::at_c<N>(fvec);
}
Функция работает, как и ожидалось, но я хотел бы получить индекс из вектора boost::mpl и использовать его в этой функции, а не передавать его функции в качестве параметра шаблона. Но я так и не понял, как это сделать.
Может ли кто-нибудь дать мне подсказку?
1 ответ
Вы можете использовать алгоритм поиска, чтобы получить "итератор", указывающий на первое вхождение типа в последовательности MPL. Что-то вроде:
typedef boost::mpl::find<TypeVector, T>::type MplIter;
и затем запросите вектор слияния в позиции этого "итератора":
return boost::fusion::at_c<MplIter::pos::value>(fvec);
Однако я не понимаю, почему вы используете вектор MPL вообще. IIUC, вы бы хотели определить getValue как:
template<class T>
T getValue(FusionVector_t fvec)
{
typedef boost::mpl::find<TypeVector, T>::type MplIter;
return boost::fusion::at_c<MplIter::pos::value>(fvec);
}
который может работать, только если TypeVector и FusionVector_t "содержат" одну и ту же последовательность типов. В таком случае, почему бы не использовать FusionVector_t и написать:
template<class T>
T getValue(FusionVector_t fvec)
{
return *boost::fusion::find<T>(fvec);
}
Более того, если вы хотите использовать "T" в качестве "индекса" в последовательности Fusion, это имеет смысл, только если данный тип появляется только один раз в последовательности. Таким образом, fusion:: set может показаться более подходящим, чем вектор. В этом случае у вас будет:
typedef boost::fusion::set<char, int, long> FusionSet_t;
template<class T>
T getValue(FusionSet_t fset)
{
return boost::fusion::at_key<T>(fset);
}