Я много играл с новыми лямбда-кодами C ++ 11, и требование полного указания аргумента шаблона является настоящим тормозом. Синтаксис, который я бы хотел бы использовать , выглядит примерно так:
#include <vector>
#include <algorithm>
struct foo
{
void bar() {}
};
int main()
{
vector<foo> v(10);
for_each(v.begin(), v.end(), [](f) {f.bar();});
^^^
}
Есть ли способ приблизить что-нибудь к этому? Библиотека Boost с Phoenix в порядке, но синтаксис для вызова функций-членов требует лотов пластины котла - я полагаю, что после C ++ 11 простота вызова функций-членов в сочетании с автоматическим выводом Phoenix типа. *
Текущая идея
Я объяснил это синтаксисом:
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
Что работает, но вы должны добавить возможность для каждого типа (например, ADD_AUTO_LAMBDA_SUPPORT(foo);
). Он также имеет ограничение на то, что все поддерживаемые типы не могут иметь неоднозначных членов.
Полный код для этого:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
struct foo
{
foo() : x(3) {}
int x;
void f() { cout << x << endl;}
};
struct bar
{
bar() : y(133.7) {}
double y;
void b() { cout << y << endl;}
};
struct combo : foo, bar { };
struct _a
{
_a(foo& f) : offset(reinterpret_cast<combo*>(&f)) {}
_a(bar& b) : offset(reinterpret_cast<combo*>((char*)&b - 2*sizeof(foo))) {}
combo* operator->() { return offset; }
private:
combo* offset;
};
int main()
{
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
}
Затем вы могли бы использовать магию шаблона и препроцессора для генерации _a
и combo
, но проблема возникает, когда у вас есть неоднозначные имена (например, третья структура с функцией b()
- вам нужен способ устраните неоднозначность их, о которых я не могу думать в настоящее время.