考虑这两个结构:
struct point {
int x,y;
};
struct pinfo {
struct point p;
unsigned long flags;
};
一个改变观点的函数:
void p_map(struct point &p);
是否可以使用boost(例如boost :: bind或boost :: lambda)来创建与以下函数等效的函数:
void pi_map(struct pinfo &pi) { p_map(pi.p); }
-edit:更新以获取更多信息:
此功能的初衷是在for_each中使用它。 例如,给定此功能:
void p_map(struct point &p)
{
p.x += 1;
p.y += 1;
}
我可以写:
void foreach(std::vector<struct pinfo> &pi_vec)
{
for_each(pi_vec.begin(), pi_vec.end(), pi_map);
}
正如答案中所建议的那样,可以用成员变量绑定 boost :: lambda,并创建一个替代for_each版本:
void foreach2(std::vector<struct pinfo> &pi_vec)
{
boost::function<void (pinfo&)> pi_map2 = bind(&p_map, bind(&pinfo::p, _1));
for_each(pi_vec.begin(), pi_vec.end(), pi_map2);
}
我对这种方法的问题是,gcc(v.4.3.2)没有内联 foreach2版本的pi_map和p_map函数。
为foreach1函数生成的x86代码是:
0000000000400dd0 <foreach(std::vector<pinfo, std::allocator<pinfo> >&)>:
400dd0: 48 8b 57 08 mov 0x8(%rdi),%rdx
400dd4: 48 8b 07 mov (%rdi),%rax
400dd7: 48 39 c2 cmp %rax,%rdx
400dda: 74 14 je 400df0 <foreach(std::vector<pinfo, std::allocator<pinfo> >&)+0x20>
400ddc: 0f 1f 40 00 nopl 0x0(%rax)
400de0: 83 00 01 addl $0x1,(%rax)
400de3: 83 40 04 01 addl $0x1,0x4(%rax)
400de7: 48 83 c0 10 add $0x10,%rax
400deb: 48 39 c2 cmp %rax,%rdx
400dee: 75 f0 jne 400de0 <foreach(std::vector<pinfo, std::allocator<pinfo> >&)+0x10>
400df0: f3 c3 repz retq
实现for_each,不调用任何函数。在另一 因为,为foreach2生成的代码更加复杂 优化,并且(似乎)内联映射函数。
然而,这个问题似乎是一个哲学的,而不是一个实际的问题 使用现代桌面处理器,因为(奇怪的是)我的机器上的性能 两种版本都相似。
答案 0 :(得分:6)
你可以使用boost :: lambda,member variables can be bound与bind
以与成员函数相同的方式执行此操作:
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
using namespace boost::lambda;
boost::function<void (pinfo&)> pi_map = bind(&p_map, bind(&pinfo::p, _1));