Я много играл с новыми лямбдами 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();});
^^^
}
Есть ли способ получить что-то приблизительно близкое к этому? Библиотека Phoenix от Boost в порядке, но синтаксис для вызова функций-членов требует много "котельной" пластины - я полагаю, что мне нужна простота вызова функций-членов в 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()
- вам нужен способ их разграничения, который я не могу придумать в данный момент.