lambda 宏如何创建 lambda?

Kis*_*ish 21 c macros lambda gcc function-pointers

我在GitHub上找到了这段代码,但不是很明白:

#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Run Code Online (Sandbox Code Playgroud)

然后:

int (*max)(int, int) = lambda(int,
                             (int x, int y) {
                                 return x > y ? x : y;
                             });

int max_value = max(1, 2);
// max_value is 2
Run Code Online (Sandbox Code Playgroud)

里面的下划线是做什么的#define,它是如何返回函数指针的?

Tho*_*ger 11

使用这个宏,

int (*max)(int, int) = lambda(int,
                              (int x, int y) {
                                  return x > y ? x : y;
                              });
Run Code Online (Sandbox Code Playgroud)

扩展为:

int (*max)(int, int) = ({
    int _ (int x, int y) { return x > y ? x : y; }
    _;
});
Run Code Online (Sandbox Code Playgroud)

在花括号中,这使用 GCC 的嵌套函数来创建执行所需操作的函数。在内部范围内,它的名称为_

然后,正如 interjay 所指出的,使用了 GCC 的语句表达式。实际上,函数_被分配给了指针max

如果没有使用这样的宏,则可以以不同的方式编写并用作:

int val1 = 4;
int val2 = -30;

int perform_operation(int (*op)(int, int)) {
    int new_val = op(val1, val2);
    val1 = val2;
    val2 = new_val;
    return new_val;
}

int enclosing_function (void) {
    // Create max "lambda"
    int (*max)(int, int);
    {
        // Curly braces limit the scope of _
        int _ (int x, int y) { return x > y ? x : y; }
        max = _;
    }

    return perform_operation(max);
}
Run Code Online (Sandbox Code Playgroud)

可以在此代码示例中比较三种方法。


JL2*_*210 8

这称为语句表达式并创建一个“lambda”(或嵌套函数)并返回一个指向它的指针。它是特定于 GNU C 的。

宏扩展为:

int (*max)(int, int) = ({ int _ (int x, int y) { return x > y ? x : y; } _; })
Run Code Online (Sandbox Code Playgroud)

所述_在端部是像return

下划线实际上是创建并“返回”的函数的名称。使用它是因为它是一个不常用的标识符(有充分的理由;_很可能是描述性最少的标识符)。

使用语句表达式的原因是在语句表达式_的作用域退出后不会定义。

所以,通过宏:

#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Run Code Online (Sandbox Code Playgroud)

ret_type是“lambda”的返回类型。_是其中使用的函数的名称,因为它是一个不常见的标识符名称。_body由函数的参数和主体组成。尾随_“返回”“lambda”。

此代码可在Let's Destroy C(这是一个合适的名称)中找到。你不应该使用它。它将使您的代码仅在支持 GNU C 扩展的编译器上工作。相反,只需编写一个函数或宏。

如果您经常使用这样的结构或想要更多功能,我建议使用 C++。使用 C++,您可以执行类似的操作拥有可移植的代码。