Вы также можете отделить функцию «занять вторую пару» от «вычислить MULT * VAL» и «добавить что-то в аккумулятор».
Несмотря на то, что вам не нужно повышать, чтобы сделать это, они уже создали большую часть «функциональной» среды программирования. Если вы не можете использовать boost, вам понадобится собственный шаблон магии. Не слишком сложно, хотя.
#include <map>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iostream>
Теперь я считаю, что лучше поместить умножение в класс.
struct SMyStruct
{
int MULT;
int VAL;
long f() const { return MULT*VAL; }
};
Создайте универсальный функтор для 'take second of pair':
// a 'take-second' functor
template< typename at_pair >
struct to_second_t : public std::unary_function< at_pair, typename at_pair::second_type > {
const typename at_pair::second_type& operator()( const at_pair & p ) const {
return p.second;
}
};
Это выглядит сложно, но это просто общий способ сказать: «сначала сделай это, а затем сделай это с результатом»:
// compose two functors (simplified)
template< typename at_F, typename at_G >
struct compose_t : public std::unary_function< typename at_F::argument_type, typename at_G::result_type >{
at_F f;
at_G g;
compose_t( at_F& f, at_G& g ): f( f ), g(g) {}
typename at_G::result_type operator()( const typename at_F::argument_type& v ) const {
return g( f( v ) );
}
};
template< typename at_F, typename at_G >
compose_t<at_F, at_G> compose( at_F& f, at_G& g ) { return compose_t<at_F,at_G>( f, g ); }
// compose two functors (a unary one, and a binary one)
//
template< typename at_F, typename at_G >
struct compose2_t : public std::binary_function< typename at_F::first_argument_type, typename at_G::argument_type, typename at_G::result_type >{
at_F f;
at_G g;
compose2_t( at_F& f, at_G& g ): f( f ), g(g) {}
typename at_G::result_type operator()( const typename at_F::first_argument_type& a1, const typename at_G::argument_type& v ) const {
return f( a1, g( v ) );
}
};
template< typename at_F, typename at_G >
compose2_t<at_F, at_G> compose2( at_F& f, at_G& g ) { return compose2_t<at_F,at_G>( f, g ); }
И, наконец, воплощение всего этого в жизнь:
int main()
{
typedef std::map<int, SMyStruct > tMap;
tMap m;
SMyStruct s = {1,2};
m[1].VAL = 1; m[1].MULT = 3;
m[2].VAL = 2; m[2].MULT = 10;
m[3].VAL = 3; m[3].MULT = 2;
// mind, this is not LISP (yet)
long total = std::accumulate( m.begin(), m.end(), 0,
compose2(
std::plus<int>(),
compose(
to_second_t<tMap::value_type>(),
std::mem_fun_ref( &SMyStruct::f ) ) )
);
std::cout << "total: " << total <<std::endl;
return 0;
}