2009-06-07 68 views
2

考慮到這兩個結構中:映射包含結構與升壓

struct point { 
    int x,y; 
}; 

struct pinfo { 
    struct point p; 
    unsigned long flags; 
}; 

和一個函數,改變一個觀點:

void p_map(struct point &p); 

是否有可能使用升壓(如提高::綁定或升壓::拉姆達)來創建一個功能等效採用:

void pi_map(struct pinfo &pi) { p_map(pi.p); } 

-edit:更新additiona l信息:

這個函數的初衷是在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 ::拉姆達綁定成員變量,並創建另一種版本的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生成的代碼更爲複雜,而且似乎沒有(似乎)內聯映射函數。

但是,這個問題似乎是一個哲學,而不是現實的桌面處理器的實際問題,因爲(奇怪的是)我的機器 的性能對於兩個版本都是相似的。

回答

6

你可以用的boost ::拉姆達做到這一點,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)); 
+0

大+1。非常漂亮的寶石。 – 2009-06-08 00:04:29