I started to play around with the boost fusion and mpl library and got stuck with a quite simple problem.
I declared the following types:
typedef boost::mpl::vector<char, int, long> TypeVector;
typedef boost::fusion::vector<char, int, long> FusionVector_t;
Now I wanted to write a function that gets me the value from the FusionVector.
template<size_t N typename T>
T getValue(FusionVector_t fvec)
{
return boost::fusion::at_c<N>(fvec);
}
The function works as expected but I would like to get the index from the boost::mpl vector and use it in this function and not pass it to the function as a template parameter. But I did not figure out so far how to do this.
Could someone give me a hint?
You can use the find algorithm to get an "iterator" pointing to the first occurence of a type in an MPL sequence. Something like:
typedef boost::mpl::find<TypeVector, T>::type MplIter;
and then query the fusion vector at that "iterator"'s position:
return boost::fusion::at_c<MplIter::pos::value>(fvec);
However, I don't see why you use the MPL vector at all. IIUC, you'd like to define getValue as:
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);
}
which can work only if TypeVector and FusionVector_t "contain" the same sequence of types. In that case, why not only use FusionVector_t and write:
template<class T>
T getValue(FusionVector_t fvec)
{
return *boost::fusion::find<T>(fvec);
}
Moreover, if you want to use "T" as an "index" into the Fusion sequence, this only makes sense if a given type appears only once in the sequence. A fusion::set would thus seem more appropriate than a vector. In that case, you'd have:
typedef boost::fusion::set<char, int, long> FusionSet_t;
template<class T>
T getValue(FusionSet_t fset)
{
return boost::fusion::at_key<T>(fset);
}