0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++ invoke與function的區(qū)別在哪?

程序喵大人 ? 來(lái)源:程序喵大人 ? 2023-09-04 09:11 ? 次閱讀

C++ invoke

invoke是C++17標(biāo)準(zhǔn)引入的一個(gè)函數(shù)模板,用來(lái)調(diào)用可調(diào)用對(duì)象(Callable Object,如函數(shù)指針、函數(shù)對(duì)象、成員函數(shù)指針等)并返回結(jié)果。

invoke提供了統(tǒng)一的調(diào)用語(yǔ)法,無(wú)論可調(diào)用對(duì)象的類型是什么,都可以使用同一種方式進(jìn)行調(diào)用。

b22b07da-4aba-11ee-97a6-92fbcf53809c.png

在C++17之前,調(diào)用不同類型的可調(diào)用對(duì)象需要使用不同的語(yǔ)法,比如直接調(diào)用函數(shù)、使用類對(duì)象的運(yùn)算符重載操作符()來(lái)調(diào)用函數(shù)對(duì)象、使用成員函數(shù)指針來(lái)調(diào)用類成員函數(shù)等等。這些調(diào)用方式雖然能用,但是不夠靈活,而invoke解決了這種不一致的問(wèn)題。

invoke函數(shù)的實(shí)現(xiàn)原理是通過(guò)使用SFINAE(Substitution Failure Is Not An Error)技術(shù)來(lái)判斷可調(diào)用對(duì)象的類型,并根據(jù)類型調(diào)用對(duì)應(yīng)的調(diào)用方式。因此,無(wú)論可調(diào)用對(duì)象的類型是什么,都可以使用invoke函數(shù)來(lái)調(diào)用,而不需要使用不同的語(yǔ)法。

下面是invoke的示例代碼:

#include 
#include 


void foo(int a, int b)
{
    std::cout << "a + b = " << a + b << std::endl;
}


class Bar
{
public:
    void operator()(int a, int b)
{
        std::cout << "a - b = " << a - b << std::endl;
    }
};


int main()
{
    int a = 10, b = 5;
    std::invoke(foo, a, b); // 調(diào)用普通函數(shù)
    Bar bar;
    std::invoke(bar, a, b); // 調(diào)用函數(shù)對(duì)象
    std::invoke(&Bar::operator(), bar, a, b); // 調(diào)用成員函數(shù)
    std::function f = foo;
    std::invoke(f, a, b); // 調(diào)用std::function對(duì)象
    return 0;
}

總結(jié):std::invoke 提供了一種通用的函數(shù)調(diào)用語(yǔ)法,可以方便地調(diào)用各種可調(diào)用對(duì)象。

function與invoke的區(qū)別

std::function和std::invoke是兩個(gè)不同的東西,功能也不同。std::function是一個(gè)函數(shù)對(duì)象的封裝器,可以用來(lái)封裝任意類型的可調(diào)用對(duì)象,比如函數(shù)指針、lambda表達(dá)式等,而 std::invoke 則是一個(gè)函數(shù)模板,用于在統(tǒng)一的接口下調(diào)用可調(diào)用對(duì)象。

比如,我們可以使用std::function來(lái)存儲(chǔ)一個(gè)函數(shù)指針:

#include 
#include 


void foo(int a, int b)
{
    std::cout << "foo(" << a << ", " << b << ")" << std::endl;
}


int main()
{
    std::function f = foo;
    f(1, 2);
}

上述代碼中,我們將函數(shù)指針foo封裝成了一個(gè)std::function對(duì)象f,然后通過(guò)調(diào)用f(1, 2)來(lái)調(diào)用函數(shù)foo。

std::invoke的作用是提供一種通用的函數(shù)調(diào)用語(yǔ)法,可以用統(tǒng)一的方式來(lái)調(diào)用各種可調(diào)用對(duì)象,而不必關(guān)心它們具體是什么類型。

比如,可以使用std::invoke來(lái)調(diào)用一個(gè)東西,無(wú)論這個(gè)東西是函數(shù)指針、函數(shù)對(duì)象還是成員函數(shù)指針:

#include 
#include 


void foo(int a, int b)
{
    std::cout << "foo(" << a << ", " << b << ")" << std::endl;
}


class Bar {
public:
    void bar(int a, int b) const
{
        std::cout << "Bar::bar(" << a << ", " << b << ")" << std::endl;
    }
};


int main()
{
    std::invoke(foo, 1, 2);


    Bar b;
    std::invoke(&Bar::bar, &b, 1, 2);
}

上面代碼,使用std::invoke分別調(diào)用了函數(shù)foo和類Bar的成員函數(shù)bar,并傳遞了相應(yīng)的參數(shù)。

總結(jié),std::function和std::invoke的使用場(chǎng)景是不同的。std::function 適用于需要存儲(chǔ)可調(diào)用對(duì)象的場(chǎng)景,而std::invoke則適用于統(tǒng)一調(diào)用各種不同類型的可調(diào)用對(duì)象的場(chǎng)景。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7435

    瀏覽量

    163522
  • C++語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    147

    瀏覽量

    6951
  • 封裝器
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    5855

原文標(biāo)題:C++ invoke與function的區(qū)別

文章出處:【微信號(hào):程序喵大人,微信公眾號(hào):程序喵大人】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    樹(shù)莓派和香蕉派的區(qū)別在哪

    樹(shù)莓派和香蕉派到底有什么區(qū)別?國(guó)產(chǎn)還是英產(chǎn)的區(qū)別?就算山寨也有山寨的區(qū)別,如果不是山寨那到的區(qū)別在哪
    發(fā)表于 03-12 14:49

    請(qǐng)問(wèn)REV C和REV B的版本區(qū)別在哪里?

    REV C 和REV B的版本區(qū)別在哪里?
    發(fā)表于 08-22 06:39

    模擬地與信號(hào)地的區(qū)別在哪里?

    模擬地與信號(hào)地的區(qū)別在哪里?在復(fù)雜混合信號(hào)PCB設(shè)計(jì)中有哪些注意事項(xiàng)?
    發(fā)表于 04-23 06:19

    TDD與FDD的區(qū)別在哪里?

    TDD與FDD的區(qū)別在哪里?TD-SCDMA系統(tǒng)優(yōu)勢(shì)有哪些?
    發(fā)表于 05-25 06:03

    string類型數(shù)據(jù)與《string.h》頭文件的區(qū)別在哪里?

    string的含義是什么?string與vector容器的區(qū)別在哪c中的字符串是什么?string類型數(shù)據(jù)與《string.h》頭文件的區(qū)別在哪里?
    發(fā)表于 07-05 07:18

    數(shù)字舵機(jī)與模擬舵機(jī)的區(qū)別在哪?

    舵機(jī)是什么?數(shù)字舵機(jī)的工作原理是什么?數(shù)字舵機(jī)與模擬舵機(jī)區(qū)別在哪?
    發(fā)表于 07-13 06:16

    相電流和線電流的區(qū)別在哪

    什么是相電流?什么是線電流?相電流和線電流的區(qū)別在哪?
    發(fā)表于 09-29 07:44

    JTAG和SWD的區(qū)別在哪

    JTAG和SWD的區(qū)別在哪?USART和UART的區(qū)別在哪?
    發(fā)表于 10-08 09:01

    sizeof和strlen函數(shù)的區(qū)別在哪

    野指針是指指針指向的位置是不可知的,主要成因是什么?sizeof和strlen函數(shù)的區(qū)別在哪?鏈表和數(shù)組的區(qū)別在哪?
    發(fā)表于 12-24 07:19

    SoftMAC和FullMAC的區(qū)別在哪

    Wifi設(shè)備的協(xié)議棧是怎樣的?SoftMAC和FullMAC的區(qū)別在哪呢?SoftMAC和FullMAC分別有哪些優(yōu)勢(shì)呢?
    發(fā)表于 03-10 08:00

    RTK和GPS定位的區(qū)別在哪里?

    RTK和GPS定位的區(qū)別在哪里?
    發(fā)表于 05-08 10:08 ?76次下載

    串口屏和并口屏的區(qū)別在哪

    串口屏還是并口屏好用?區(qū)別在哪里?
    的頭像 發(fā)表于 01-23 09:53 ?9499次閱讀

    C++中struct和class的區(qū)別?

    C++中struct和class的區(qū)別是什么?C++中struct和class的最大區(qū)別在于: ? ? ? ? struct的成員默認(rèn)是公有的, 而class的成員默認(rèn)是私有的,
    的頭像 發(fā)表于 03-10 17:41 ?731次閱讀

    functioninvoke區(qū)別

    std::function和std::invoke是兩個(gè)不同的東西,功能也不同。std::function 是一個(gè)函數(shù)對(duì)象的封裝器,可以用來(lái)封裝任意類型的可調(diào)用對(duì)象,比如函數(shù)指針、lambda表達(dá)式等
    的頭像 發(fā)表于 04-27 15:13 ?695次閱讀

    梯形絲桿和滾珠絲桿的區(qū)別在哪里?

    梯形絲桿和滾珠絲桿的區(qū)別在哪里?
    的頭像 發(fā)表于 03-28 17:48 ?2310次閱讀
    梯形絲桿和滾珠絲桿的<b class='flag-5'>區(qū)別在哪</b>里?