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
\

本文來自博客園,作者:xrlong,轉載請注明原文鏈接:http://www.rzrgm.cn/xrlong/p/18793445
版權聲明:本作品采用 「署名-非商業性使用-相同方式共享 4.0 國際」許可協議(CC BY-NC-SA 4.0) 進行許可。

浙公網安備 33010602011771號