首页 > 其他分享 >lambda实现递归

lambda实现递归

时间:2024-08-30 10:14:54浏览次数:13  
标签:调用 递归 实现 Actor RecursiveSearchRef 组件 lambda

lambda实现递归

在 C++ 中,lambda 表达式在定义时实际上不能直接调用自己,因为 lambda 在定义时没有名字。要让一个 lambda 自我引用,你需要使用一个技巧:将 lambda 自身作为参数传递给自己,从而实现递归。

为什么 Lambda 自身在定义时无法被调用?

  1. 匿名性:Lambda 表达式是匿名的,编译器在定义时不为其生成名称,因此无法在其内部直接引用或调用自己。
  2. 捕获和名称:在 lambda 定义时,虽然可以捕获外部变量,但不能直接引用自身,因为 lambda 的名字在定义时尚未确定。

解决方案:使用引用捕获

通过使用 lambda 的引用捕获(通常是将 lambda 自身作为参数传递),你可以在 lambda 内部实现递归。假设我们要查找一个 AActor 下所有的 URectLightComponent,我们可以使用一个 lambda 函数来递归地遍历所有子组件。

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Components/RectLightComponent.h"
#include "GameFramework/Actor.h"

class FRectLightFinder
{
public:
    static void FindRectLightComponents(AActor* Actor, TArray<URectLightComponent*>& OutRectLightComponents)
    {
        if (!Actor)
        {
            return;
        }

        // 定义 lambda 函数进行递归
        auto RecursiveSearch = [](USceneComponent* Component, TArray<URectLightComponent*>& OutComponents, auto& RecursiveSearchRef)
        {
            if (!Component)
            {
                return;
            }

            // 检查是否是 RectLightComponent
            if (URectLightComponent* RectLightComponent = Cast<URectLightComponent>(Component))
            {
                OutComponents.Add(RectLightComponent);
            }

            // 递归查找所有子组件
            for (USceneComponent* Child : Component->GetChildrenComponents(true))
            {
                RecursiveSearchRef(Child, OutComponents, RecursiveSearchRef);
            }
        };

        // 从 Actor 的根组件开始递归
        RecursiveSearch(Actor->GetRootComponent(), OutRectLightComponents, RecursiveSearch);
    }
};

解释

  1. Lambda 函数RecursiveSearch 是一个递归的 lambda 表达式,它负责遍历组件及其子组件。注意,lambda 使用 auto& RecursiveSearchRef 参数来递归调用自己。为了在 lambda 内部递归调用自身,必须通过引用捕获。
  2. RecursiveSearchRef:这参数用于实现递归调用,因为 lambda 自身在定义时还无法被调用。我们将它作为参数传递给 lambda,并在递归时引用它。
  3. 递归逻辑:在 RecursiveSearch 内部,我们首先检查当前组件是否是 URectLightComponent。如果是,我们将其添加到结果数组中。然后我们递归地遍历当前组件的所有子组件。
  4. 启动递归:在 FindRectLightComponents 函数中,我们从 Actor 的根组件开始调用递归 lambda。

关键点

  • auto& RecursiveSearchRef:在 lambda 的参数列表中,使用 auto& RecursiveSearchRef 来传递 lambda 自身的引用。这允许 lambda 在其内部递归调用自身。
  • 递归调用:通过 RecursiveSearchRef 引用,lambda 可以递归调用自己,实现遍历所有子组件的功能。

这种方式有效地绕过了 lambda 定义时无法直接自引用的问题,允许你在 lambda 内部实现递归逻辑。

标签:调用,递归,实现,Actor,RecursiveSearchRef,组件,lambda
From: https://www.cnblogs.com/Dreammoon/p/18388117

相关文章

  • 基于Python+Flask实现民办高校教师职称晋升系统
    作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,有较为丰富的相关经验。期待与各位高校教师、企业......
  • 基于SpringBoot的大学生就业需求分析系统设计与实现
    作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,有较为丰富的相关经验。期待与各位高校教师、企业......
  • 基于Python实现校园爱心帮扶平台
    作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,有较为丰富的相关经验。期待与各位高校教师、企业......
  • Spring框架中如何实现国际化(i18n)?
    在Spring框架中实现国际化(i18n)主要涉及以下几个步骤:1.准备资源文件首先,你需要为不同语言准备资源文件。这些资源文件通常放在类路径下的特定目录中,如src/main/resources/下的messages.properties文件。对于不同的语言和地区,你可以创建对应的.properties文件,例如me......
  • Linux--实现U盘,SD卡的自动挂载
    1.编辑/etc/init.d/rsC或S10mdev文件在/etc/init.d/rsC或S10mdev中加入以下语句:echo/sbin/mdev>/proc/sys/kernel/hotplug当有热插拔事件产生时,内核会调用/proc/sys/kernel/hotplug文件里指定的应用程序来处理热插拔事件。把/sbin/mdev写到/proc/sys/kernel/hotplug文件......
  • 数据无界:大型企业如何实现多区域文件安全传输的无缝体验?
    随着企业全球化发展,大型企业分支机构的分布越来越广泛,多区域文件传输需求也随之增加。目前大型企业多区域文件数据存储和传输交换现状如下:1.文件存储现状:集中和分散并存,局部集中,整体分散;2.文件存储管理:不同区域、分支机构、业务部门,文件存储方案差异化,各自建设,分别管理,比如:FTP服......
  • 汉诺塔和递归
    目录需求背景、限制条件、化简模拟盘子的移动步骤递归实现Code分析练习1需求背景、限制条件、化简汉诺塔就是一个由柱子和盘子组成的玩具,它有一些玩法上的限制,主要是规定了盘子移动有限制。想理解到递归本质,汉诺塔是个不错的载体。怎么体会?在盘子移动的过程中。#盘子的......
  • Redis高可用方案:使用Keepalived实现主备双活
    注意:请确保已经安装Redis和keepalived,本文不在介绍如何安装。1、使用版本说明Redis版本:5.0.2Keepalived版本:1.3.5Linux版本:Centos7.9查看Redis版本:/usr/local/redis/bin/redis-cli-v查看Keepalived版本信息:rpm-qa|grepkeepalived或者keepalived-v2、功能实现......
  • 快速排序python实现
    defquick_sort(arr,left,right):origin_left=leftorigin_right=rightpivot_data=arr[left]#枢轴上的值(基准值),就是开始用来比较的值,一般是随机选择一个位置,这儿选择最左边的值#blank_pos=left#最左边的值已经复制到pivot中了,所以这块......
  • 访问者模式:如何实现对象级别的矩阵结构?
    今天我们先来看一个原理看似很简单,但是理解起来有一定难度,使用场景相对较少的行为型模式:访问者模式。一、模式原理分析访问者模式的原始定义是:允许在运行时将一个或多个操作应用于一组对象,将操作与对象结构分离。这个定义会比较抽象,但是我们依然能看出两个关键点:一个是运行时使......