亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文詳解C++仿函數(shù)

 更新時(shí)間:2025年04月03日 09:28:38   作者:今夜有雨.  
本文主要介紹了一文詳解C++仿函數(shù),主要用途是提供一種靈活的方式來(lái)定義和操作數(shù)據(jù),下面就來(lái)介紹一下仿函數(shù)的使用,感興趣的可以了解一下

一、仿函數(shù)的定義

在C++中,仿函數(shù)(Functors)或稱為函數(shù)對(duì)象(Function Objects)是重載了調(diào)用操作符operator()的類或結(jié)構(gòu)體,這使得這些類的對(duì)象可以像函數(shù)一樣被調(diào)用。仿函數(shù)的主要用途是提供一種靈活的方式來(lái)定義和操作數(shù)據(jù)。通過(guò)創(chuàng)建自定義的仿函數(shù),你可以將待定的邏輯封裝在一個(gè)對(duì)象中,并在需要時(shí)將其傳遞給算法或容器。

二、仿函數(shù)的特性

在這里插入圖片描述

我們用例子來(lái)解釋

  • 例子一
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//定義一個(gè)仿函數(shù)用來(lái)比較兩個(gè)整數(shù)
struct CompareInt{
    bool operator()(int a,int b) const{
        return a<b;
    }
};

int main()
{
    vector<int> numbers={5,2,9,1,5,6};

    //使用STL中的sort算法和自定義的仿函數(shù)對(duì)vector進(jìn)行排序
    std::sort(numbers.begin(),numbers.end(),CompareInt());

    //輸出排序后的vector
    for(int num:numbers)
    {
        cout<<num<<" ";
    }
    cout<<endl;

    return 0;
}

在以上這個(gè)例子中我們的仿函數(shù)結(jié)構(gòu)體中重載了小括號(hào)(),傳入了兩個(gè)參數(shù),達(dá)到完成比較兩個(gè)數(shù)大小的功能,當(dāng)我們?cè)谥骱瘮?shù)std::sort(numbers.begin(),numbers.end(),CompareInt())中,CompareInt看似是一個(gè)對(duì)象,其實(shí)它是一個(gè)仿函數(shù),函數(shù)的返回值是bool類型的,傳入的bool類型的值決定了是升序還是倒序。

  • 例子二 仿函數(shù)可以封裝狀態(tài)
    仿函數(shù) 的一個(gè)關(guān)鍵特點(diǎn)是它可以封裝狀態(tài),這意味著它們可以擁有數(shù)據(jù)成員,這些成員可以在不同的函數(shù)調(diào)用之間保持狀態(tài),以下是一個(gè)簡(jiǎn)單的C++仿函數(shù)示例,它包含了一個(gè)狀態(tài)變量(internal_sum),并在每次調(diào)用的時(shí)候?qū)⑵渑c輸入?yún)?shù)相加:
#include <iostream>
using namespace std;

//定義一個(gè)仿函數(shù)類,帶有內(nèi)部狀態(tài)
class Accumulator{
    //構(gòu)造函數(shù),初始化內(nèi)部狀態(tài)
public:
    Accumulator(int initial_sum=0) : internal_sum(initial_sum) {}
    //重載operator(),使其接受一個(gè)整數(shù)參數(shù),將其與內(nèi)部狀態(tài)相加,并返回結(jié)果
    int operator()(int value){
        internal_sum+=value; //修改內(nèi)部狀態(tài)
        return internal_sum; //返回累加后的結(jié)果
    }
    //獲取當(dāng)前內(nèi)部狀態(tài)
    int get_sum() const {
        return internal_sum;
    }
private:
    int internal_sum;//仿函數(shù)的內(nèi)部狀態(tài)
};

int main()
{
    //創(chuàng)建Accumulator類的實(shí)例,初始化內(nèi)部狀態(tài)為0
    Accumulator accumulator;

    //使用仿函數(shù)來(lái)調(diào)用它,即使用它跟使用一個(gè)函數(shù)一樣
    cout<<"After adding 5:"<<accumulator(5)<<endl;
    cout<<"After adding 3:"<<accumulator(3)<<endl;
    cout<<"Current sum:"<<accumulator.get_sum()<<endl;

    //創(chuàng)建另一個(gè)Accumulator實(shí)例,初始化內(nèi)部狀態(tài)為10
    Accumulator accumulator2(10);

    //使用這個(gè)實(shí)例進(jìn)行累加
    cout<<"initial sum 10,after adding 2:"<<accumulator2(2)<<endl;



    return 0;
}

在這個(gè)例子中,Accumulator類是一個(gè)仿函數(shù),它有一個(gè)私有的整數(shù)成員internal_sum,用于存儲(chǔ)累加的值,構(gòu)造函數(shù)允許我們初始化internal_sum的值,我們每調(diào)用依次這個(gè)仿函數(shù),它就會(huì)相應(yīng)的累加,當(dāng)然我們創(chuàng)建的第二個(gè)累加器的實(shí)例對(duì)象,它們兩個(gè)的值互不影響。

  • 仿函數(shù)可以當(dāng)參數(shù)傳遞
#include <iostream>

// 定義一個(gè)仿函數(shù)類
class MyFunctor {
public:
    // 重載 operator()
    int operator()(int value) const {
        return value * 2;
    }
};

// 定義一個(gè)接受仿函數(shù)作為參數(shù)的函數(shù)
void applyFunctor(const MyFunctor& functor, int value)
{
    std::cout << "經(jīng)過(guò)仿函數(shù)處理過(guò)后的值: " << functor(value) << std::endl;
}

int main() {
    // 創(chuàng)建仿函數(shù)實(shí)例
    MyFunctor functor;
    // 調(diào)用接受仿函數(shù)為參數(shù)的函數(shù)
    applyFunctor(functor, 5);

    return 0;
}

在以上這個(gè)例子中,我們定義了一個(gè)仿函數(shù)類,里面重載了operator(),使得我們?cè)趯?shí)例化函數(shù)對(duì)象時(shí),調(diào)用這個(gè)

  • 仿函數(shù)可以作為模板參數(shù)
    仿函數(shù)確實(shí)可以作為模板參數(shù)使用,因?yàn)樗鼈兙哂凶约旱奈ㄒ活愋?。模板參?shù)可以接受任何類型,包括類類型,而仿函數(shù)就是類類型的一種。下面是一個(gè)代碼樣例,展示了如何使用仿函數(shù)作為模板參數(shù):
#include <iostream>
#include <vector>
#include <algorithm>

// 定義一個(gè)仿函數(shù)類,用于將整數(shù)乘以2
class MultiplyByTwo {
public:
    // 重載 operator(),實(shí)現(xiàn)對(duì)傳入整數(shù)的乘以2操作
    int operator()(int value) const {
        return value * 2;
    }
};

// 定義一個(gè)接受仿函數(shù)作為模板參數(shù)的函數(shù)模板
// 該函數(shù)模板用于對(duì) vector 中的每個(gè)元素應(yīng)用仿函數(shù)進(jìn)行變換
template <typename Functor>
void transformVector(std::vector<int> &vec, Functor functor) {
    // 遍歷 vector 中的每個(gè)元素,并應(yīng)用仿函數(shù)進(jìn)行變換
    for (auto &item : vec) {
        item = functor(item);
    }
}

int main() {
    // 初始化一個(gè)包含整數(shù)的 vector
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用 MultiplyByTwo 仿函數(shù)類作為模板參數(shù),調(diào)用 transformVector 函數(shù)
    // 對(duì) vector 中的每個(gè)元素進(jìn)行乘以2的操作
    transformVector(vec, MultiplyByTwo());

    // 輸出變換后的 vector 元素
    for (auto item : vec) {
        std::cout << item << " ";
    }
    std::cout << std::endl;

    //也可以直接使用lambda表達(dá)式作為模板參數(shù)
    transformVector(vec,[](int value){return value*3;});
    //再次輸出變換后的值
    for (auto item : vec) {
        std::cout << item << " ";
    }
    std::cout << std::endl;

    return 0;
}

在這個(gè)例子中,transformVector是一個(gè)函數(shù)模板,它接受一個(gè)std::vector和一個(gè)仿函數(shù)作為參數(shù)。這個(gè)函數(shù)模板使用仿函數(shù)來(lái)變換vector中的每一個(gè)元素。在主函數(shù)中,我們首先使用MultiplyByTwo仿函數(shù)作為模板參數(shù)調(diào)用transformVector函數(shù),然后使用一個(gè)lambda表達(dá)式作為模板參數(shù)再次調(diào)用transformVector函數(shù)。這展示了仿函數(shù)和lambda表達(dá)式都可以作為模板參數(shù)傳遞給函數(shù)模板

  • 謂詞
    在計(jì)算機(jī)語(yǔ)言中,謂詞通常指條件表達(dá)式的求值返回真或假的過(guò)程

1.一元謂詞(Unary Predicate)
一元謂詞通常用于判斷單個(gè)元素是否滿足某個(gè)條件,以下是一個(gè)使用std::remove_if和一元謂詞的簡(jiǎn)單例子,它移除std::vector中的所有偶數(shù)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 定義一元謂詞函數(shù),檢查整數(shù)是否為偶數(shù)
// 參數(shù):
// - num: 需要檢查的整數(shù)
// 返回值:
// - 如果 num 是偶數(shù),返回 true;否則返回 false
bool isEven(int num) {
    return num % 2 == 0;
}

int main() {
    // 初始化一個(gè)包含整數(shù)的 vector
    vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 使用 std::remove_if 和一元謂詞 isEven 移除所有偶數(shù)
    // std::remove_if 將所有滿足條件(即偶數(shù))的元素移動(dòng)到 vector 的末尾,并返回新末尾的迭代器
    // vec.erase 則刪除從新末尾到原末尾的所有元素,從而實(shí)現(xiàn)移除操作
    vec.erase(remove_if(vec.begin(), vec.end(), isEven), vec.end());

    // 輸出處理之后的 vector 元素
    for (auto i : vec) {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

2.二元謂詞(Binary Predicate)
二元謂詞通常用于比較兩個(gè)元素,以下是一個(gè)使用std::sort和二元謂詞的簡(jiǎn)單例子,它根據(jù)自定義的比較規(guī)則對(duì)vector進(jìn)行排序:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 定義二元謂詞函數(shù),用于比較兩個(gè)整數(shù)的大?。ń敌蚺判颍?
// 參數(shù):
// - a: 第一個(gè)整數(shù)
// - b: 第二個(gè)整數(shù)
// 返回值:
// - 如果 a 大于 b,返回 true;否則返回 false
bool CompareInt(int a, int b) {
    return a > b;
}

int main() {
    // 初始化一個(gè)包含整數(shù)的 vector
    vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};

    // 使用 std::sort 和二元謂詞 CompareInt 對(duì) vector 進(jìn)行降序排序
    // std::sort 接受三個(gè)參數(shù):起始迭代器、結(jié)束迭代器和比較函數(shù)
    // 比較函數(shù) CompareInt 確定了排序順序?yàn)榻敌?
    std::sort(vec.begin(), vec.end(), CompareInt);

    // 輸出處理之后的 vector 元素
    for (auto i : vec) {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

在這兩個(gè)例子中,我分別定義了一個(gè)一元謂詞和一個(gè)二元謂詞,一元謂詞用于判斷單個(gè)元素是否為偶數(shù),而二元謂詞用于比較兩個(gè)元素的大小,然后,我們使用這些謂詞與標(biāo)準(zhǔn)庫(kù)算法結(jié)合在一起,實(shí)現(xiàn)相應(yīng)的功能。

三、仿函數(shù)的相對(duì)性能優(yōu)勢(shì)

  • 通常說(shuō)仿函數(shù)(也稱為函數(shù)對(duì)象或functor)比函數(shù)指針執(zhí)行速度快,這并不是一個(gè)絕對(duì)的結(jié)論。在大多數(shù)情況下,它們之間的性能差異是非常小的,甚至在現(xiàn)代的編譯器優(yōu)化下可能幾乎無(wú)法測(cè)量。但是,有幾個(gè)原因可能會(huì)導(dǎo)致在某些特定情況下仿函數(shù)相對(duì)更快:
  • 內(nèi)聯(lián)優(yōu)化:在仿函數(shù)作為類成員函數(shù)或重載操作符,更有可能被編譯器內(nèi)聯(lián)(inline),這可以減少函數(shù)調(diào)用的開銷。相比之下,函數(shù)指針指向的函數(shù)通常不會(huì)被內(nèi)聯(lián),除非編譯器特別確定這樣做是安全的。
  • 狀態(tài)局部性:仿函數(shù)可以包含狀態(tài)(即數(shù)據(jù)成員),這些狀態(tài) 可以與其成員函數(shù)緊密的存儲(chǔ)在一起。這種緊密性可以提高數(shù)據(jù)訪問(wèn)的局部性,從而提高緩存利用率,進(jìn)而可能提高性能。
  • 類型安全:仿函數(shù)可以通過(guò)模板和類型系統(tǒng)提供更高級(jí)別的類型安全性。雖然這不會(huì)直接影響執(zhí)行速度,但它可以減少因類型錯(cuò)誤而導(dǎo)致的運(yùn)行時(shí)開銷。
  • 無(wú)額外的間接引用:函數(shù)指針需要額外的簡(jiǎn)介引用來(lái)訪問(wèn)目標(biāo)函數(shù)。雖然這種間接引用在現(xiàn)代處理器上通常是非常快的,但在某些極端情況下,它可能會(huì)成為性能瓶頸。
  • 編譯時(shí)優(yōu)化:由于仿函數(shù)是類的實(shí)例,編譯器可以對(duì)它們進(jìn)行更廣泛的優(yōu)化,例如通過(guò)消除虛擬函數(shù)調(diào)用的開銷(如果仿函數(shù)沒(méi)有使用虛函數(shù))或使用特定的類型特定優(yōu)化。

總結(jié)

本文主要介紹了 C++ 中的仿函數(shù),包括仿函數(shù)的定義、特性和相對(duì)性能優(yōu)勢(shì)。仿函數(shù)是重載了調(diào)用操作符 operator () 的類或結(jié)構(gòu)體,可像函數(shù)一樣被調(diào)用,主要用途是提供靈活方式定義和操作數(shù)據(jù)。其特性有可封裝狀態(tài)、能當(dāng)參數(shù)傳遞、可作為模板參數(shù)及作為謂詞使用。相對(duì)性能優(yōu)勢(shì)方面,可能比函數(shù)指針執(zhí)行速度快,原因包括內(nèi)聯(lián)優(yōu)化、狀態(tài)局部性、類型安全、無(wú)額外間接引用和編譯時(shí)優(yōu)化等。

到此這篇關(guān)于一文詳解C++仿函數(shù)的文章就介紹到這了,更多相關(guān)C++仿函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C++-二階構(gòu)造模式、友元

    詳解C++-二階構(gòu)造模式、友元

    這篇文章主要介紹了C++-二階構(gòu)造模式、友元,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • C字符串操作函數(shù)的實(shí)現(xiàn)詳細(xì)解析

    C字符串操作函數(shù)的實(shí)現(xiàn)詳細(xì)解析

    以下是對(duì)C語(yǔ)言中字符串操作函數(shù)的實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • VSCode配置C++環(huán)境的方法步驟(MSVC)

    VSCode配置C++環(huán)境的方法步驟(MSVC)

    這篇文章主要介紹了VSCode配置C++環(huán)境的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • C++封裝IATHOOK類實(shí)例

    C++封裝IATHOOK類實(shí)例

    這篇文章主要介紹了C++封裝IATHOOK類的實(shí)現(xiàn)方法,對(duì)IAT的HOOK實(shí)例進(jìn)行了封裝,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • C++中std::setw()的用法解讀

    C++中std::setw()的用法解讀

    這篇文章主要介紹了C++中std::setw()的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語(yǔ)言超詳細(xì)分析多進(jìn)程的概念與使用

    C語(yǔ)言超詳細(xì)分析多進(jìn)程的概念與使用

    在一個(gè)項(xiàng)目中并發(fā)執(zhí)行任務(wù)時(shí)多數(shù)情況下都會(huì)選擇多線程,但有時(shí)候也會(huì)選擇多進(jìn)程,例如可以同時(shí)運(yùn)行n個(gè)記事本編輯不同文本,由一個(gè)命令跳轉(zhuǎn)到另外一個(gè)命令,或者使用不同進(jìn)程進(jìn)行協(xié)作
    2022-08-08
  • C++學(xué)生信息管理系統(tǒng)

    C++學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家想詳細(xì)介紹了C++學(xué)生信息管理系統(tǒng)的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • C++ deque與vector對(duì)比的優(yōu)缺點(diǎn)

    C++ deque與vector對(duì)比的優(yōu)缺點(diǎn)

    這篇文章主要介紹了C++中deque與vector相比的優(yōu)勢(shì)與劣勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • C語(yǔ)言單鏈表實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    C語(yǔ)言單鏈表實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言單鏈表實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C++實(shí)現(xiàn)刪除txt文件中指定內(nèi)容的示例代碼

    C++實(shí)現(xiàn)刪除txt文件中指定內(nèi)容的示例代碼

    這篇文章主要介紹了C++實(shí)現(xiàn)刪除txt文件中指定內(nèi)容的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評(píng)論