在C++ 11中实现干净的lambda函数

Ayj*_*jay 9 c++ lambda templates c++11

我一直在玩新的C++ 11 lambda,并且完全指定模板参数的要求是一个真正的拖累.我的语法喜欢使用是类似于下面的内容:

#include <vector>
#include <algorithm>

struct foo
{
    void bar() {}
};

int main()
{
    vector<foo> v(10);

    for_each(v.begin(), v.end(), [](f) {f.bar();});
                                   ^^^
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以得到任何接近这个的东西吗?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();});
Run Code Online (Sandbox Code Playgroud)

哪个有效,但您必须添加每种类型的功能(例如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();});
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用一些模板和预处理神奇的同时生成_acombo,但问题来的时候你有明确的名称(例如,第三结构用.b()功能-你需要一种方法来消除歧义他们,我不能在那一刻想到的.

Mar*_* Ba 13

注意:我完全同意这[](auto f){ ... }是非常可取的!

虽然我们没有那个,但是好老了typedef呢?它只添加一行,非常"低技术",使lambda易于阅读:

typedef const map<key_type, value_type>::value_type&  ?p_t;
for_each(m.begin(), m.end(), [&](?p_t x) {...});
Run Code Online (Sandbox Code Playgroud)

  • Unicode字符?? 在*my*C++源码中?! (13认同)
  • @Ayjay:嘿,为什么不呢?:-P(我不知道编译器是否会吞下它.这只是为了好玩.) (3认同)
  • @phresnel - 当然,该标准允许实现支持unicode源字符.它不需要它,但它也不禁止它. (3认同)
  • 麻省理工学院Lisp机器使用的旧"太空学员"键盘实际上有一个特殊的lambda键:http://en.wikipedia.org/wiki/Space-cadet_keyboard (2认同)
  • 该标准不允许源代码中的unicode字符. (2认同)

edA*_*a-y 0

如果您愿意使用宏并使用所有设置,使用 decltype 的快捷方式宏还不够吗?就像是:

#define T_FOR_EACH( begin_, end_, var_, func_ ) \
  for_each( (begin_), (end_), [](decltype(*begin_) var_) func_ )
Run Code Online (Sandbox Code Playgroud)

那么你可以:

T_FOR_EACH(x.begin(), x.end(), &f, {f->f();} );
Run Code Online (Sandbox Code Playgroud)

&我不在定义中放置变量的原因是,使用这种格式仍然可以指定您想要的所有类型说明符以及它是引用还是副本。

如果语法错误,请原谅,我周围没有 C++11 编译器,我可以用它来测试其中的任何一个,这只是一个想法。