lambda函数的递归调用(不用std::function)

本文展示了如何在C++中使用Lambda表达式实现递归函数,包括一个计算阶乘的示例和多函数互相调用的场景。在Visual Studio 2022环境下测试通过,但在VS2002中也兼容。

测试环境VC2022

void T01()
{
	auto lpfn = [](int x, auto f)->int
	{
		if (x == 1)
			return 1;
		return x * f(x - 1, f);
	};
	int xx = lpfn(12, lpfn);
}

以上是计算12以内阶乘的一个测试函数,函数名无法放在中括号里就放到小括号,做为一个参数传递。在VS2002中测试通过

这种方式还可以多个函数互调:

void T02()
{
	auto lpfn1 = [](int x, auto f1, auto f2)->int
	{
		if (x == 1)
			return f2();
		return x * f1(x - 1, f1, f2);
	};
	auto lpfn2 = [lpfn1]()->int
	{
		//lpfn1(0, lpfn1, lpfn1);		//通不过编译
		return 1;
	};

	int x = lpfn1(10, lpfn1, lpfn2);
	//int y = lpfn1(10, lpfn2, lpfn1);		//这行通不过编译
}

C++中,由于lambda的匿名特性,无法直接在lambda内部递归调用自身,因为它的类型是在声明时确定的,而在递归调用时,Lambda表达式的类型还没有完全确定。为解决这个问题,可以借助`std::function`,它是一个可调用对象包装器,能容纳除了类成员函数指针以外所有的可调用对象,适合作为回调函数使用,是一个可以存储任何可调用对象的通用容器,只要其签名与`std::function`的模板参数匹配即可。 以下是几种C++lambda函数递归调用的示例: ### 示例一:斐波那契数列递归C++11中,lambda表达式函数递归往往会带上`<functional>`头文件,示例代码如下: ```cpp #include <iostream> #include <functional> int main() { std::function<int(int)> fib = [&fib] (int n) { if(n <= 2) return 1; else return fib(n-1) + fib(n-2); }; std::cout << fib(5) << std::endl; return 0; } ``` 此代码通过`std::function<int(int)>`定义了一个可调用对象`fib`,其参数和返回值类型都为`int`,在lambda表达式内部通过`[&fib]`捕获`fib`的引用,从而实现递归调用计算斐波那契数列 [^3]。 ### 示例二:简单递减递归 ```cpp #include <iostream> #include <functional> void T01() { std::function<void(int)> lpfn = [&lpfn](int n) { if (n == 0) return; lpfn(n - 1); }; lpfn(10); } int main() { T01(); return 0; } ``` 该示例中,`std::function<void(int)>`定义了一个参数为`int`,无返回值的可调用对象`lpfn`,在lambda表达式内部捕获`lpfn`的引用,实现递减递归调用 [^4]。 ### 示例三:错误的直接递归尝试 ```cpp #include <iostream> int main() { auto fun1 = [](int param) { std::cout << "fun1 called " << param << "\n"; if (param > 100) return; fun1(++param); // 这是错误的,无法编译通过 }; fun1(1); return 0; } ``` 此代码直接在lambda内部递归调用`fun1`,由于lambda无法直接递归调用自身,所以该代码无法编译通过 [^1][^2]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值