【问题标题】:mapping of a contained struct with boost使用 boost 映射包含的结构
【发布时间】:2009-06-07 23:04:09
【问题描述】:

考虑这两个结构:

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

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

【问题讨论】:

    标签: c++ performance gcc boost


    【解决方案1】:

    您可以使用 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));
    

    【讨论】:

    • 大+1。非常漂亮的隐藏宝石。
    • 您好,感谢您的回复!我已经编辑了我的原始问题以添加有关此方法的一些信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 2021-01-19
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    相关资源
    最近更新 更多