使用boost映射包含的结构

时间:2009-06-07 23:04:09

标签: c++ performance gcc boost

考虑这两个结构:

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生成的代码更加复杂 优化,并且(似乎)内联映射函数。

然而,这个问题似乎是一个哲学的,而不是一个实际的问题 使用现代桌面处理器,因为(奇怪的是)我的机器上的性能 两种版本都相似。

1 个答案:

答案 0 :(得分:6)

你可以使用boost :: lambda,member variables can be boundbind以与成员函数相同的方式执行此操作:

 #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));