最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++?如何將Lambda轉(zhuǎn)換成函數(shù)指針

 更新時間:2022年11月05日 11:16:44   作者:斗酒神僧  
這篇文章主要介紹了C++?如何將Lambda轉(zhuǎn)換成函數(shù)指針,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

沒有捕獲任何變量的Lambda表達(dá)式可以轉(zhuǎn)換成與它的調(diào)用原型一致的函數(shù)指針。

參考下面的代碼

void example1()
{
? ? auto add = [](int x, int y)
? ? {
? ? ? ? return x + y;
? ? };
? ? int x = 2, y = 3;
? ? int z1 = add(x, y); ? ? ? ? ? ? ? ? ?// 調(diào)用Lambda
? ? int(*f)(int, int) = add; ? ? ? ? ? ? // Lambda轉(zhuǎn)換成函數(shù)指針
? ? int z2 = f(x, y); ? ? ? ? ? ? ? ? ? ?// 調(diào)用函數(shù)
? ? cout << z1 << ", " << z2 << endl;
}

Lambda是實現(xiàn)了函數(shù)調(diào)用運算符的匿名類(anonymous class)。對于每一個Lambda,編譯器創(chuàng)建匿名類,并定義相應(yīng)的數(shù)據(jù)成員存儲Lambda捕獲的變量。沒有捕獲變量的Lambda不包含任何含成員變量。

一個沒有任何成員變量(包括沒有虛函數(shù)表指針)的類型,在空指針上調(diào)用成員函數(shù)也不會有任何的問題,因為它的成員函數(shù)不會通過this指針訪問內(nèi)存。

當(dāng)Lambda向函數(shù)指針的轉(zhuǎn)換時,編譯器為Lambda的匿名類實現(xiàn)函數(shù)指針類型轉(zhuǎn)換運算符。

上面的例子中,編譯器實現(xiàn)operator int(*)(int, int)。

下面是Visual C++編譯器為語句int(*f)(int, int) = add生成的64位匯編代碼:

lea ? ? ? ? rcx,[add] ?
call ? ? ? ?<lambda_0e153cdea67ea404383c23c1022dd325>::operator int (__cdecl*)(int,int)?
mov ? ? ? ? qword ptr [f],rax ?

第1行,變量"add"的地址存入rcx寄存器;第2行,調(diào)用匿名類的函數(shù)指針類型轉(zhuǎn)換運算符;第3行,返回結(jié)果存入變量f。

提示:在默認(rèn)的成員函數(shù)調(diào)用約定__thiscall下,this指針通過rcx寄存器傳遞, 有關(guān)__thiscall的詳細(xì)內(nèi)容,請參考:https://docs.microsoft.com/en-us/cpp/cpp/thiscall。

下面是類型轉(zhuǎn)換運算符實現(xiàn)的一行關(guān)鍵匯編代碼

lea ? ? ? ? rax,[<lambda_0e153cdea67ea404383c23c1022dd325>::<lambda_invoker_cdecl>]?

這一行把匿名類的名為lambda_invoker_cdecl的函數(shù)地址存入用于返回結(jié)果的寄存器rax。因為只有類的靜態(tài)函數(shù)可以轉(zhuǎn)換成非成員函數(shù)指針,所以lambda_invoker_cdecl是靜態(tài)函數(shù)。下面是此函數(shù)其中一段匯編代碼:

xor ? ? ? ? rcx,rcx ?
call ? ? ? ?<lambda_0e153cdea67ea404383c23c1022dd325>::operator()?

第一行,rcx寄存器清0,即this指針置0;第二行,調(diào)用operator()。

綜合上面的分析,得出Lambda轉(zhuǎn)換成函數(shù)指針的一種可能的實現(xiàn)方式,參考下面的代碼:

typedef int(*FUNCADD)(int, int);

// 實現(xiàn)兩個整數(shù)相加的函數(shù)對象
class add_function_object
{
public:
? ? // 函數(shù)調(diào)用運算符
? ? int operator()(int x, int y)const
? ? {
? ? ? ? return x + y;
? ? }
? ? // 函數(shù)指針類型轉(zhuǎn)換運算符
? ? operator FUNCADD()const
? ? {
? ? ? ? return add;
? ? }
private:
? ? static int add(int x, int y)
? ? {
? ? ? ? add_function_object* obj = nullptr;
? ? ? ? return obj->operator()(x, y);
? ? }
};

void example2()
{
? ? int x = 2, y = 3;
? ? add_function_object add;
? ? int z1 = add(x, y);
? ? auto fadd = add.operator FUNCADD();
? ? int z2 = fadd(x, y);
? ? cout << z1 << ", " << z2 << endl;
}

從C++17起,沒有捕獲任何變量的Lambda可以用作值類型模板實參,參考下面的代碼:

typedef int (*INTEGER_OPERATION)(int, int);

int do_integer_operation(INTEGER_OPERATION op, int x, int y)
{
? ? return op(x, y);
}

template <INTEGER_OPERATION op>
int integer_operation_t(int x, int y)
{
? ? return op(x, y);
}

void example3()
{
? ? auto add = [](int x, int y)
? ? {
? ? ? ? return x + y;
? ? };
? ? auto sub = [](int x, int y)
? ? {
? ? ? ? return x - y;
? ? };
? ? int z1 = integer_operation_t<add>(2, 3);
? ? int z2 = do_integer_operation(integer_operation_t<sub>, 2, 3);
? ? cout << "z1 : " << z1 << ", z2 : " << z2 << endl;
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++位操作實戰(zhàn)掩碼、提取與組裝

    C++位操作實戰(zhàn)掩碼、提取與組裝

    在C++編程中,位操作是基礎(chǔ)而強大的技術(shù),允許在二進(jìn)制級別上操作數(shù)據(jù),對性能優(yōu)化、內(nèi)存節(jié)省和底層硬件控制至關(guān)重要,文章探討了掩碼操作、字節(jié)提取與組裝等技術(shù),并介紹了bitset類模板的使用,幫助處理二進(jìn)制數(shù)據(jù),通過實例解析如何設(shè)置、清除、檢查特定位
    2024-10-10
  • 詳解C語言內(nèi)核字符串轉(zhuǎn)換方法

    詳解C語言內(nèi)核字符串轉(zhuǎn)換方法

    在內(nèi)核開發(fā)模式下,初始化字符串也需要調(diào)用專用的初始化函數(shù),如下分別初始化ANSI和UNCODE字符串,本文我們就來看看代碼是如何實現(xiàn)的
    2022-09-09
  • C語言遞歸操作用法總結(jié)

    C語言遞歸操作用法總結(jié)

    這篇文章主要介紹了C語言遞歸操作用法,結(jié)合實例形式總結(jié)分析了C語言遞歸操作的原理、實現(xiàn)技巧與相關(guān)應(yīng)用,需要的朋友可以參考下
    2016-02-02
  • C++深入詳解單例模式與特殊類設(shè)計的實現(xiàn)

    C++深入詳解單例模式與特殊類設(shè)計的實現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C++單例模式和特殊類的設(shè)計,單例模式這種類型的設(shè)計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-06-06
  • 詳解C語言中的函數(shù)、數(shù)組與指針

    詳解C語言中的函數(shù)、數(shù)組與指針

    這篇文章主要介紹了C語言中的函數(shù)、數(shù)組與指針,本文給大家介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • C++常量詳解一(常量指針與常量引用的初始化)

    C++常量詳解一(常量指針與常量引用的初始化)

    這篇文章主要介紹了C++常量詳解一(常量指針與常量引用的初始化),需要的朋友可以參考下
    2017-06-06
  • 使用C++描繪心形

    使用C++描繪心形

    本文給大家分享的是一個使用c++繪制心形的代碼,雖然情人節(jié)已經(jīng)過去了,但是只要有心,天天都是情人節(jié)~~哈哈,讓那些說程序猿都是木頭的人去死吧。
    2015-03-03
  • Qt qml實現(xiàn)動態(tài)輪播圖效果

    Qt qml實現(xiàn)動態(tài)輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了Qt和qml實現(xiàn)動態(tài)輪播圖效果的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-12-12
  • C語言算法練習(xí)之?dāng)?shù)組元素排序

    C語言算法練習(xí)之?dāng)?shù)組元素排序

    這篇文章主要為大家介紹了C語言算法練習(xí)中數(shù)組元素排序的實現(xiàn)方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-09-09
  • C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)

    C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)

    這篇文章主要介紹了C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)的相關(guān)資料,需要的朋友可以參考下
    2017-05-05

最新評論

龙门县| 武穴市| 腾冲县| 无为县| 右玉县| 喀喇沁旗| 镇赉县| 丘北县| 古浪县| 于田县| 依安县| 高雄市| 阳高县| 定兴县| 津南区| 呈贡县| 双牌县| 河津市| 金川县| 肇东市| 阿坝| 栾川县| 安泽县| 金沙县| 当涂县| 博客| 琼海市| 平原县| 噶尔县| 长兴县| 新乐市| 始兴县| 贺兰县| 通辽市| 陆河县| 陇西县| 垦利县| 洪雅县| 尼勒克县| 泗水县| 申扎县|