Код
C++ (Qt)typedef type_list< double, int, std::string, float > list_of_types;
struct cals_sum : public any_visitor< double, list_of_types >
{
double m_sum;
cals_sum () : m_sum() {}
double operator()( const std::string & str ) { return m_sum += std::stod(str); }
template <class T>
double operator()( const T & val ) { return m_sum += double( val ); }
};
struct to_string : public any_visitor< std::string, list_of_types >
{
std::string operator()( const std::string & str ) const { return str; }
template <class T>
std::string operator()(const T & val) const { return std::to_string(val); }
};
int main()
{
std::list< boost::any > many = {123, 3.14, 5.6f, std::string("2.71")};
cals_sum visitor;
for ( const auto & x : many )
apply_any_visitor( visitor, x );
std::cout << visitor.m_sum << std::endl;
return 0;
}
Ну плюс модифицировать apply часть для возможности работы с неконстантными визитерами.
Код
C++ (Qt)template <class Visitor, class TypeList>
struct any_cast_helper
{
static typename Visitor::result_type get(const boost::any & any, Visitor & visitor)
{
if (any.type() == typeid(typename TypeList::first_type))
return visitor(boost::any_cast<typename TypeList::first_type >(any));
return any_cast_helper<Visitor, typename TypeList::next_type_list>::get(any, visitor);
}
static typename Visitor::result_type get(const boost::any & any, const Visitor & visitor)
{
if (any.type() == typeid(typename TypeList::first_type))
return visitor(boost::any_cast<typename TypeList::first_type>(any));
return any_cast_helper<Visitor, typename TypeList::next_type_list>::get(any, visitor);
}
};
template <class Visitor>
struct any_cast_helper<Visitor, null_type>
{
static typename Visitor::result_type get(const boost::any &, Visitor &) throw(std::bad_cast)
{
throw std::bad_cast();
}
static typename Visitor::result_type get(const boost::any &, const Visitor &) throw(std::bad_cast)
{
throw std::bad_cast();
}
};
template <class Visitor>
typename Visitor::result_type apply_any_visitor(const Visitor & visitor, const boost::any & any)
{
return any_cast_helper<Visitor, typename Visitor::type_list>::get(any, visitor);
}
template <class Visitor>
typename Visitor::result_type apply_any_visitor( Visitor & visitor, const boost::any & any)
{
return any_cast_helper<Visitor, typename Visitor::type_list>::get(any, visitor);
}
Вместо расчета суммы можно осуществить паковку данных с учетом последовательности прихода.