使用boost映射包含的结构

yni*_*ous 2 c++ performance gcc boost

考虑到这两个结构:

struct point {
    int x,y;
};

struct pinfo {
    struct point p;
    unsigned long flags;
};
Run Code Online (Sandbox Code Playgroud)

还有一个改变观点的功能:

void p_map(struct point &p);
Run Code Online (Sandbox Code Playgroud)

是否可以使用boost(例如boost :: bind或boost :: lambda)创建一个等效的函数:

void pi_map(struct pinfo &pi) { p_map(pi.p); }
Run Code Online (Sandbox Code Playgroud)

-edit:更新以获取更多信息:

这个函数的初衷是在for_each中使用它.例如,给定此功能:

void p_map(struct point &p)
{
    p.x += 1;
    p.y += 1;
}
Run Code Online (Sandbox Code Playgroud)

我可以写:

void foreach(std::vector<struct pinfo> &pi_vec)
{
    for_each(pi_vec.begin(), pi_vec.end(), pi_map);
}
Run Code Online (Sandbox Code Playgroud)

正如在答案中建议的那样,可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

我对这种方法的问题是,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
Run Code Online (Sandbox Code Playgroud)

它实现了for_each,而不调用任何函数.另一方面,由于优化,为foreach2生成的代码更复杂,并且(似乎)没有内联映射函数.

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

sth*_*sth 6

你可以用boost :: lambda来做,成员变量可以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));
Run Code Online (Sandbox Code Playgroud)