我在这方面做了一些工作,这就是我想出的。它有效,但不完整,因为只有范围绑定到第一个参数的一元函数和二元函数的模板。如果有人更进一步并使其更通用,请在此处发回。
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <boost/range/value_type.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/foreach.hpp>
template <class Range>
struct GetRangeValue
{
typedef typename boost::range_value<Range>::type Value;
};
template <class Function, class Range>
struct BindForEachBase
{
BindForEachBase(Function *f, Range &r) : function(f), range(r) { }
Function *const function;
Range ⦥
};
template <class Function, class Range>
struct BindForEach1
: BindForEachBase<Function, Range>
{
BindForEach1(Function *f, Range &r)
: BindForEachBase(f, r)
{ }
void operator()()
{
BOOST_FOREACH(GetRangeValue<Range>::Value v, range) (*function)(v);
}
};
template <class Function, class Range>
BindForEach1<Function, Range>
bindForEach(Function *f, Range &r)
{
return BindForEach1<Function, Range>(f, r);
}
template <class Function, class Range, class A1>
struct BindForEach2
: BindForEachBase<Function, Range>
{
BindForEach2(Function *f, Range &r)
: BindForEachBase(f, r)
{ }
void operator()(A1 a1)
{
boost::function1<void, GetRangeValue<Range>::Value> f(boost::bind(*this->function, _1, a1));
bindForEach(&f, range)();
}
};
template <class Function, class Range, class Placeholder1>
typename boost::enable_if
<
boost::is_placeholder<Placeholder1>,
BindForEach2<Function, Range, typename boost::function_traits<Function>::arg2_type>
>::type
bindForEach(Function *f, Range &r, Placeholder1 p1)
{
return BindForEach2<Function, Range, boost::function_traits<Function>::arg2_type >(f, r);
}
void f(int x, int y)
{
std::cout << x + y << ',';
}
#include <boost/assign/std/vector.hpp>
#include <vector>
using namespace boost::assign;
void go()
{
std::vector<int> v1;
v1 += 1,2,3;
boost::function<void(int y)> f_bound = bindForEach(f, v1, _1);
f_bound(10); // prints 11,12,13,
}