I am trying to write a translation function that takes a value and a series of lookup tables as arguments. The lookup table has the following declaration:
template< typename fromType, typename toType> struct DataTranslator;
I can get it to work with the following declarations of the transformable template function:
template< typename Return, typename Direction, typename ValType, typename TransType> Return translate(ValType val, TransType& trans); template< typename Return, typename Direction, typename ValType, typename TransType, typename... OtherTrans> Return translate(ValType val, TransType& trans, OtherTrans&... others);
Then I can do something like the following:
DataTranslator<specificBaud, universalBaud>::type baudTranslator; DataTranslator<universalBaud, std::string>::type baudCmdTranslator; specificBaud myBaud; .... std::string result = translate<std::string, forward_trans>(myBaud, baudTranslator, baudCmdTranslator);
but if I changed the declaration of my translation functions to:
template< typename Return, typename Direction, typename ValType, typename FT, typename TT> Return translate(ValType val, typename DataTranslator<FT, TT>::type& trans); template< typename Return, typename Direction, typename ValType, typename FT, typename TT, typename... OtherTrans> Return translate(ValType val, typename DataTranslator<FT, TT>::type& trans, OtherTrans&... others);
When making a transferred call, I get an inappropriate function call error. I am using GCC 4.5 for my compiler with the flag -std = C ++ 0x.
My main question is: why does the second version not work? I saw examples (basically, the Tuple class proposed in one of the sentences for varidic templates), where they make this type of type decomposition for its specialization.
Full test code:
#include <iostream> #include <utility> #include <string> #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/tag.hpp> #include <boost/mpl/if.hpp> #include <boost/function.hpp> #include <tr1/type_traits> enum silly {car, boat, plane, truck}; enum furry {bunny, dog, cat, donkey, critter}; struct forward_trans {}; struct reverse_trans {}; template<typename from, typename to> struct DataTranslator { typedef std::pair<from, to> Element; typedef boost::multi_index_container<Element, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag<forward_trans>, boost::multi_index::member<Element, typename Element::first_type, &Element::first> >, boost::multi_index::ordered_unique< boost::multi_index::tag<reverse_trans>, boost::multi_index::member<Element, typename Element::second_type, &Element::second> > > > type; // Added after Answer accepted as what I fixed to get this to work type trans; }; template<typename R, typename I> struct forward_extractor { R operator()(I it) { return it->second; } }; template<typename R, typename I> struct reverse_extractor { R operator()(I it) { return it->first; } }; template<typename from, typename to> struct FunctionTranslator { typedef boost::function<to (from) > forward_type; typedef boost::function<from (to) > reverse_type; }; /*template<typename R, typename D, typename V, typename Trans> R translate(V v, Trans& t); template<typename R, typename D, typename V, typename Trans, typename... Others> R translate(V v, Trans& t, Others&... o); */ template<typename R, typename D, typename V, typename FT, typename TT, typename... others> R translate(V val, boost::function<TT(FT)> trans, others&... o) { TT temp = trans(val); return static_cast<R>(translate<R, D>(temp, o...)); } template<typename R, typename D, typename V, typename FT, typename TT> R translate(V val, boost::function<TT(FT)>& func) { return static_cast<R>(func(val)); } template<typename R, typename D, typename V, typename FT, typename TT> R translate(V val, typename DataTranslator<FT, TT>::type& trans) { typedef typename DataTranslator<FT, TT>::type::template index<D>::type lookup_table; typedef typename lookup_table::iterator lut_iterator; lookup_table& lut = boost::multi_index::get<D>(trans); R not_found; typedef typename boost::mpl::if_c<std::tr1::is_same<D, forward_trans>::value, forward_extractor<TT, lut_iterator>, typename boost::mpl::if_c<std::tr1::is_same<D, reverse_trans>::value, reverse_extractor<FT, lut_iterator>, bool>::type>::type extractor_type; extractor_type ext; lut_iterator it = lut.find(val); if(it == lut.end()) { return not_found; } return static_cast<R>(ext(it)); } template<typename R, typename D, typename V, typename FT, typename TT, typename... others> R translate(V val, typename DataTranslator<FT, TT>::type& trans, others&... o) { typedef typename DataTranslator<FT, TT>::type::template index<D>::type lookup_table; typedef typename lookup_table::iterator lut_iterator; lookup_table& lut = boost::multi_index::get<D>(trans); R not_found; typedef typename boost::mpl::if_c<std::tr1::is_same<D, forward_trans>::value, forward_extractor<TT, lut_iterator>, typename boost::mpl::if_c<std::tr1::is_same<D, reverse_trans>::value, reverse_extractor<FT, lut_iterator>, bool>::type >::type extractor_type; extractor_type ext; lut_iterator it = lut.find(val); if(it == lut.end()) { return not_found; } return translate<R, D>(ext(it), o...); } int main(int argc, char** argv) { typedef typename DataTranslator<silly, furry>::type SillyToFurryTranslatorType; typedef typename DataTranslator<furry, std::string>::type FurryToStringTranslatorType; DataTranslator<silly, furry>::type stft; DataTranslator<furry, std::string>::type ftst; stft.insert(std::make_pair(car, dog)); stft.insert(std::make_pair(boat, cat)); ftst.insert(std::make_pair(dog, "Doggie!")); ftst.insert(std::make_pair(cat, "Earl the Dead Cat")); std::string result = translate<furry, forward_trans>(car, stft, ftst); std::cout << result << std::endl; return 0; }