C ++ lambda在捕获变量时具有不同的类型 [英] C++ lambda has a different type when it captures variable

查看:76
本文介绍了C ++ lambda在捕获变量时具有不同的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图返回一个lambda函数,该函数从其当前作用域捕获变量.当我不捕获变量时,lambda函数将返回并且可以毫无问题地执行:

I'm trying to return a lambda function which captures a variable from its current scope. When I don't capture a variable, the lambda function is returned and can be executed with no problem:

#include <iostream>

typedef void(*VoidLambda)();

VoidLambda get() {
    VoidLambda vl = []() {
        std::cout << "hello" << std::endl;
    };
    return vl;
};

int main()
{
    get()(); //prints "hello" as expected
    return 0;
}

如果vl尝试捕获变量,则编译器将不再对其进行编译:

If vl attempts to capture a variable, the compiler won't compile it anymore:

#include <iostream>

typedef void(*VoidLambda)();

VoidLambda get(const char* x) {
    VoidLambda vl = [x]() { //Error: no suitable conversion function from "lambda []void ()->void" to "VoidLambda" exists
        std::cout << x << std::endl;
    };
    return vl;
};

int main()
{
    get("hello")();
    return 0;
}

我已经尝试过将第二个lambda转换为VoidLambda,但是问题仍然存在.

I have already tried casting the second lambda to VoidLambda, but the problem remains the same.

我想知道第一个和第二个lambda表达式之间的区别是什么,以及如何解决该问题(即使用捕获功能返回lambda函数).

I'd like to know what the difference between the first and second lambda expression is, and how to solve the problem (i.e. return the lambda function with captures).

推荐答案

不捕获任何状态的Lambda函数是无状态的.因此,可以将它们建模为正态函数.如果他们需要捕获不再正确的状态:该状态需要到某个地方并且函数指针没有该状态的位置.

Lambda functions which don't capture any state are, well, stateless. Thus, it is possible to model them as a normal function. If they need to capture state that isn't true anymore: the state needs to somewhere and function pointer doesn't have a place for the state.

基本上有两种选择:

  1. 使用推导类型返回lambda函数,例如:

  1. Return the lambda function using a deduced type, e.g.:

auto get(char* x) { return [x]{ std::cout << x << "\n";  }; }

  • 返回lambda函数的类型擦除的表示形式:

  • Return a type-erased representation of the lambda function:

    std::function<void()> get(char* x) { return [x]{ std::cout << x << "\n"; }; }
    

  • 根据您的需求选择哪种.第二个在概念上更接近函数指针.第一个效率更高,但要求该功能为inline(或至少在使用时可见).

    Which one to choose depends on your needs. The second one is conceptually closer to the function pointer. The first one is more efficient but requires the function to be inline (or, at least, visible where used).

    这篇关于C ++ lambda在捕获变量时具有不同的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆