2025.3.26 鲜花

如何优雅的将 lambda 转化为函数指针

lemon
梦(ゆめ)ならばどれほどよかったでしょう
未(いま)だにあなたのことを梦(ゆめ)にみる
忘(わす)れた物(もの)を取(と)りに帰(かえ)るように
古(ふる)びた思(おも)い出(で)の埃(ほこり)を払(はら)う
戻(もど)らない幸(しあわ)せがあることを
最後(さいご)にあなたが教(おし)えてくれた
言(い)えずに隠(かく)してた昏(くら)い过去(かこ)も
あなたがいなきゃ永远(えいえん)に昏(くら)いまま
きっともうこれ以上(いじょう) 伤(きず)つくことなど
ありはしないとわかっている
あの日(ひ)の悲(かな)しみさえ
あの日(ひ)の苦(くる)しみさえ
そのすべてを爱(あい)してた あなたとともに
胸(むね)に残(のこ)り离(はな)れない
苦(にが)いレモン(れもん)の匂(にお)い
雨(あめ)が降(ふ)り止(や)むまでは帰(かえ)れない
今(いま)でもあなたはわたしの光(ひかり)
暗闇(くらやみ)であなたの背(せ)をなぞった
その轮廓(りんかく)を鲜明(せんめい)に覚(おぼ)えている
受(う)け止(と)めきれないものと出会(であ)うたび
溢(あふ)れてやまないのは涙(なみだ)だけ
何(なに)をしていたの
何(なに)を见(み)ていたの
わたしの知(し)らない横颜(よこがお)で
どこかであなたが今(いま)
わたしと同(おな)じ様(よう)な
涙(なみだ)にくれ 淋(さび)しさの中(なか)にいるなら
わたしのことなどどうか 忘(わす)れてください
そんなことを心(こころ)から愿(ねが)うほどに
今(いま)でもあなたはわたしの光(ひかり)
自分(じぶん)が思(おも)うより 恋(こい)をしていたあなたに
あれから思(おも)うように 息(いき)ができない
あんなに侧(そば)にいたのにまるで嘘(うそ)みたい
とても忘(わす)れられないそれだけが确(たし)か
あの日(ひ)の悲(かな)しみさえ
あの日(ひ)の苦(くる)しみさえ
その全(すべ)てを爱(あい)してたあなたと共(とも)に
胸(むね)に残(のこ)り离(はな)れない
苦(にが)いレモン(れもん)の匂(にお)い
雨(あめ)が降(ふ)り止(や)むまでは帰(かえ)れない
切(き)り分(わ)けた果実(かじつ)の片方(かたほう)の様(よう)に
今(いま)でもあなたはわたしの光(ひかり)

这个东西属于是一般用不到,但是万一想用了一整就是半天,趁这次整好了赶紧记一下。

众所周知的,没有捕获的 lambda 可以轻松转成函数指针,于是我们可以这么写。

bool (*f)(int, int) = [](int a, int b){return a > b;};

但是如果有捕获呢?

我们知道,lambda 可以直接访问它可以看到的全局变量,这里的全局变量是包括 static 的,所以如果我们吧捕获的变量前加上 static,也就可以不捕获直接访问了,类似:

int main(){
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	static int a = 0;
	auto f = [](){++a;};
	f();
	cout << a << endl;
}

但是这很傻,于是我们想找个更好的方式。不妨换个角度想,因为 lambda 内是可以调用 lambda 的,所以如果我们吧它变成另一个 static 的 lambda 中调用,就成功了:

template <class F>
auto T(F f){
	static auto ff = forward<F>(f);
	return [](int a, int b){return ff(a, b);};
}

bool (*f)(int, int) = T([&x](int a, int b){return a + x < b;});

美中不足的是,虽然我们成功的用 auto 避免了提前知道返回值类型,但是我们不可避免的要提前知道传参类型,不够泛化。

众所周知的,对于一个类的静态函数是也可以直接转换成函数指针的,于是我们用类来替换掉最外层的 lambda,加上一些元编程技巧(和对网上一众工程代码的简化),可以得到:

namespace Trans{
	template <class F, class... A>
	struct Fn{
		static const F *f;
		static auto R(A... a){ return (*f)(forward<A>(a)...); }
	};
	template <class F, class... A> const F *Fn<F, A...>::f;
	template <class... A, class F>
	auto Trs(F &&f){
		static F ff = forward<F>(f);
		Fn<F, A...>::f = &ff;
		return &Fn<F, A...>::R;
	}
} using Trans::Trs;

bool (*f)(int, int) = Trs<int, int>([&x](int a, int b){return a + x > b;});

也并不是很长。或许有点用?

P

\

posted @ 2025-03-26 12:15  xrlong  阅读(48)  评论(2)    收藏  举报

Loading