返回 lambda 表达式的函数

发布于 2024-10-12 18:30:39 字数 343 浏览 2 评论 0原文

我想知道是否可以在 C++11 中编写一个返回 lambda 函数的函数。当然,一个问题是如何声明这样的函数。每个 lambda 都有一个类型,但该类型无法用 C++ 表达。我不认为这会起作用:

auto retFun() -> decltype ([](int x) -> int)
{
    return [](int x) { return x; }
}

也不是这样:

int(int) retFun();

我不知道有任何从 lambda 到函数指针或类似函数的自动转换。唯一的解决方案是手工制作函数对象并返回它吗?

I wonder if it's possible to write a function that returns a lambda function in C++11. Of course one problem is how to declare such function. Each lambda has a type, but that type is not expressible in C++. I don't think this would work:

auto retFun() -> decltype ([](int x) -> int)
{
    return [](int x) { return x; }
}

Nor this:

int(int) retFun();

I'm not aware of any automatic conversions from lambdas to, say, pointers to functions, or some such. Is the only solution handcrafting a function object and returning it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深者入戏 2024-10-19 18:30:39

您不需要手工制作的函数对象,只需使用 std::function 即可,lambda 函数可以转换为该对象:

此示例返回整数恒等函数:

std::function<int (int)> retFun() {
    return [](int x) { return x; };
}

You don't need a handcrafted function object, just use std::function, to which lambda functions are convertible:

This example returns the integer identity function:

std::function<int (int)> retFun() {
    return [](int x) { return x; };
}
冰雪梦之恋 2024-10-19 18:30:39

尽管该问题专门询问 C++11,但为了其他偶然发现此问题并有权访问 C++14 编译器的人,C++14 现在允许普通函数推导返回类型。因此,只需删除 -> 即可调整问题中的示例,使其按需要工作。 decltype... 子句位于函数参数列表之后:

auto retFun()
{
    return [](int x) { return x; }
}

但是请注意,如果函数中出现多个 return;,则此方法将不起作用。这是因为返回类型推导的一个限制是所有 return 语句必须返回相同类型的表达式,但编译器为每个 lambda 对象赋予了自己唯一的类型,因此 return; 每个表达式都有不同的类型。

Though the question specifically asks about C++11, for the sake of others who stumble upon this and have access to a C++14 compiler, C++14 now allows deduced return types for ordinary functions. So the example in the question can be adjusted just to work as desired simply by dropping the -> decltype... clause after the function parameter list:

auto retFun()
{
    return [](int x) { return x; }
}

Note, however, that this will not work if more than one return <lambda>; appears in the function. This is because a restriction on return type deduction is that all return statements must return expressions of the same type, but every lambda object is given its own unique type by the compiler, so the return <lambda>; expressions will each have a different type.

紫轩蝶泪 2024-10-19 18:30:39

对于这个简单的示例,您不需要 std::function

根据标准§5.1.2/6:

没有 lambda-capture 的 lambda 表达式的闭包类型具有公共非虚拟非显式 const 转换函数,指向具有相同参数的函数的指针并返回类型作为闭包类型的函数调用运算符。此转换函数返回的值应是函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果。

因为你的函数没有捕获,这意味着 lambda 可以转换为指向 int (*)(int) 类型的函数的指针:

typedef int (*identity_t)(int); // works with gcc
identity_t retFun() { 
  return [](int x) { return x; };
}

这是我的理解,如果我是这样,请纠正我错误的。

For this simple example, you don't need std::function.

From standard §5.1.2/6:

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

Because your function doesn't have a capture, it means that the lambda can be converted to a pointer to function of type int (*)(int):

typedef int (*identity_t)(int); // works with gcc
identity_t retFun() { 
  return [](int x) { return x; };
}

That's my understanding, correct me if I'm wrong.

小情绪 2024-10-19 18:30:39

您可以从其他 lambda 函数返回 lambda 函数,因为您不应显式指定 lambda 函数的返回类型。只需在全局范围内编写类似的内容即可:

 auto retFun = []() {
     return [](int x) {return x;};
 };

You can return lambda function from other lambda function, since you should not explicitly specify return type of lambda function. Just write something like that in global scope:

 auto retFun = []() {
     return [](int x) {return x;};
 };
○愚か者の日 2024-10-19 18:30:39

你应该这样写:

auto returnFunction = [](int x){
    return [&x](){
        return x;
    }();
};

将你的返回作为函数,并像这样使用它:

int val = returnFunction(someNumber);

You should write like this:

auto returnFunction = [](int x){
    return [&x](){
        return x;
    }();
};

to get your return as a function, and use it like:

int val = returnFunction(someNumber);
陌路黄昏 2024-10-19 18:30:39

例如,如果您没有 c++ 11 并且在微控制器上运行 c++ 代码。您可以返回一个 void 指针,然后执行强制转换。

void* functionThatReturnsLambda()
{
    void(*someMethod)();

    // your lambda
    someMethod = []() {

        // code of lambda

    };

    return someMethod;
}


int main(int argc, char* argv[])
{

    void* myLambdaRaw = functionThatReturnsLambda();

    // cast it
    auto myLambda = (void(*)())myLambdaRaw;

    // execute lambda
    myLambda();
}

If you do not have c++ 11 and are running your c++ code on micro controllers for example. You can return a void pointer and then perform a cast.

void* functionThatReturnsLambda()
{
    void(*someMethod)();

    // your lambda
    someMethod = []() {

        // code of lambda

    };

    return someMethod;
}


int main(int argc, char* argv[])
{

    void* myLambdaRaw = functionThatReturnsLambda();

    // cast it
    auto myLambda = (void(*)())myLambdaRaw;

    // execute lambda
    myLambda();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文