将函数绑定到一个范围以生成一个迭代函数

我正在尝试实现我自己的可以绑定范围的
bind_range
。它应该允许这样的客户端代码:
void f(int x, int y)
{
    std::cout << x + y << ',';
}

std::vector<int> v1; // contains 1,2,3

void go()
{
    boost::function<void(int y)> f_bound = bind_range(f, v1, _1);
    f_bound(10); // prints 11,12,13,
}
在上面的代码中,我的模板
bind_range
检测到
v1
符合
ForwardRangeConcept<>
,并且其值类型与
f()
的第一个参数兼容。然后它生成一个函数对象,它将迭代
v1
,为每个值调用
f()
。 我知道上面的内容可以通过调用代码中的某种形式的for-each构造来实现,但我想采用绑定函数并在以后使用它。 以上是我想要实现的目标。我已经阅读了我的C ++模板元编程副本并查看了
boost::bind
实现,但我无法开始使用解决方案。我也有一种唠叨的感觉,这种类似的东西已经存在于Boost库的某个地方。 扩展: 绑定多个范围。例如:
std::vector<int> v10; // contains 10,20,30

void go_multiple()
{
    boost::function<void()> f_bound = bind_range(f, v10, v1);
    f_bound(); // prints 11,12,13,21,22,23,31,32,33,
}
处理退货类型。我不需要迭代调用的返回类型,但可以想象某人可能想要存储或处理每个返回值。我确信这可以用某种Lamda型结构整齐地完成。     
已邀请:
据我所知,这在Boost中不存在,因为它很容易用
for_each
bind
复制,例如:
function<void()> bound = bind(
    for_each<vector<int>::iterator, function<void(int)> >, 
    v1.begin(), v1.end(), func
);`
这很简单。您只需要创建一个模板化仿函数
bind_range
,其中包含一个带有绑定信息的构造函数(即容器和仿函数)和一个将该函数应用于容器的
operator()
。 但请注意,保存这样的仿函数以供以后使用通常很危险,因为
bind_range
对象最终可能会引用不再存在的容器。 一个简单的例子:
template<typename Container, typename Function>
struct bind_range {
    bind_range(Container& target, Function func) 
        : container(target), function(func) { }

    void operator()() {
        std::for_each(container.begin(), container.end(), function);
    }

    Function function;
    Container& container;
};
    
我不知道问题是什么。你说这可以通过调用代码中的for_each构造来实现。是的,没错。那么为什么不把for_each构造INTO到bind_range函子本身呢?我的意思是,bind_range将是一个带有operator()的结构模板。在此运算符中,您必须执行for_each。我错过了什么吗?     
我对此进行了一点研究,这就是我想出来的。它工作,但是不完整,因为只有模板用于一元函数和二元函数,其中范围绑定到第一个参数。如果有人进一步采取这种方式并使其更通用,请在此处回复。
#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 &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,
}
    

要回复问题请先登录注册