Учитывая эти две структуры:
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) не включает
Функции pi_map и p_map для версии foreach2.
Код x86, сгенерированный для функции foreach1:
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, является более сложным, из-за
оптимизации, и, похоже, не встроены в функции отображения.
Однако этот вопрос кажется скорее философским, чем практическим
с современными процессорами для настольных ПК, поскольку (как ни странно) производительность на моей машине
одинаково для обеих версий.