C++更短的lambda语法

Jon*_*an. 4 c++ lambda c++11

我是C++的新手,最近来自Swift.有没有办法得到更短的lambda语法?

我有很多行:

columns = {
    Col(_("Name"), "string", [] (Person *p) {
                                return p->Name();
                              }),
    Col(_("Age"), "int", [] (Person *p) {
                                return p->Age();
                              }),
    Col(_("Bank"), "string", [&banks] (Person *p) {
                            return banks.lookUp(p->Identifier()).Name;
                           }),
    //..etc..
};
Run Code Online (Sandbox Code Playgroud)

有些列需要更长的lambdas,但因为编写lambda的语法与它自己的内容一样长.

lambda语法可以减少吗?(通过隐式参数或隐式返回最后一个语句)

例如在Swift中我可以做这样的事情,它会是一样的:

    Col(_("Age"), "int", { $0.Age() }),
Run Code Online (Sandbox Code Playgroud)

编辑:添加了银行列作为更复杂的一个示例.

eca*_*mur 8

如果您一直在调用成员函数,则可以使用mem_fn:

Col(_("Name"), "string", std::mem_fn(&Person::Name)),
Run Code Online (Sandbox Code Playgroud)

mem_fn当通过任一指针或该对象类型的引用的工作原理.

  • 天啊,他们怎么能把它命名为“mem_”而不是“member_”?!就像 UNIX 的“creat”时代(或 DOS 的“if exit”)的闪回一样。除此之外,这还带来了额外的认知成本,因为每次看到它时,首先总是必须撤消“mem = 记忆”关联。而且它也使得不可能泛化为“member_data”,或者只是“member”,以防将来可能发生(想象一下那些带有“mem”的情况!)。 (9认同)
  • @Sz。直到此刻我还以为 `mem_` 是 `memory_` 的缩写,这对我来说没有任何意义...... (3认同)

stg*_*lov 6

使用 C++14 和宏,您可以从 javascript (ES6) 中模仿箭头函数的语法。

事实上,通常通过引用捕获所有内容就足够了。参数类型可以设置为自动,返回类型可以省略。所以C++14允许我们的最短版本是:

auto f = [&](auto x, auto y) { return x + y; };
Run Code Online (Sandbox Code Playgroud)

显然,它可以很容易地变成宏:

#define _L2(a, b, res) [&](auto a, auto b) { return res; }
#define _S2(res) _L2(_0, _1, res)
Run Code Online (Sandbox Code Playgroud)

_L2宏使用两个用户指定的参数创建一个 lambda。该_S2宏创建了一个带有名为_0and 的参数的 lambda _1。最后,我们可以使用此答案_L按参数数量重载宏。我不知道如何推断_S通过宏的参数数量。

现在我们可以这样写:

auto g = _L(x, y, x + y);    //std::plus
auto g = _S2(_0 + _1);       //std::plus
Run Code Online (Sandbox Code Playgroud)

你甚至可以做一些疯狂的事情,比如:

//turns unary accessor function into binary comparator functor
auto compByKey = _L(f, _L(x, y, f(x) < f(y)));
//sort vector<string> by length
sort(arr.begin(), arr.end(), compByKey(_L(x, x.length())));
Run Code Online (Sandbox Code Playgroud)

确实,语法仍然不像原始 javascript 或 swift 中那样清晰,但它要短得多。现在的问题是记住我们定义的所有类型的 lambdas =) 无论如何,STL 库对函数式编程并不友好......

ideone上提供完整的代码。

  • 很好的答案,也是如何有益地使用宏的一个很好的例子,特别是在函数上下文中。`#define` 通常由于它可能造成的损害而太不受欢迎。然而,“map(vec, [] (int e) { return 2*e + 1; })”读起来比“map(vec, L( 2*it + 1 ))”之类的东西要麻烦得多。然而,您需要考虑的是,以“_”和大写字母开头的标识符**保留用于实现**。 (2认同)

R S*_*ahu 5

lambda语法可以减少吗?

我不这么认为.功能的基本组件lambda可满足您的需求:

[ capture-list ] ( params ) { body }
Run Code Online (Sandbox Code Playgroud)

你可以使用C++ 11中的最小形式.

  • 旁注:最短的lambda是`[] {}` - 参数是可选的. (4认同)
  • @DieterLücking,他似乎需要函数体中的参数`p`。 (2认同)