您还可以将“取第二对”功能与“计算 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;
}