欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

在這里插入圖片描述

我們用例子來解釋

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

//定義一個仿函數(shù)用來比較兩個整數(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ù)對vector進行排序
    std::sort(numbers.begin(),numbers.end(),CompareInt());

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

    return 0;
}

在以上這個例子中我們的仿函數(shù)結構體中重載了小括號(),傳入了兩個參數(shù),達到完成比較兩個數(shù)大小的功能,當我們在主函數(shù)std::sort(numbers.begin(),numbers.end(),CompareInt())中,CompareInt看似是一個對象,其實它是一個仿函數(shù),函數(shù)的返回值是bool類型的,傳入的bool類型的值決定了是升序還是倒序。

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

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

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

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

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

    //使用這個實例進行累加
    cout<<"initial sum 10,after adding 2:"<<accumulator2(2)<<endl;



    return 0;
}

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

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

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

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

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

    return 0;
}

在以上這個例子中,我們定義了一個仿函數(shù)類,里面重載了operator(),使得我們在實例化函數(shù)對象時,調用這個

  • 仿函數(shù)可以作為模板參數(shù)
    仿函數(shù)確實可以作為模板參數(shù)使用,因為它們具有自己的唯一類型。模板參數(shù)可以接受任何類型,包括類類型,而仿函數(shù)就是類類型的一種。下面是一個代碼樣例,展示了如何使用仿函數(shù)作為模板參數(shù):
#include <iostream>
#include <vector>
#include <algorithm>

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

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

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

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

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

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

    return 0;
}

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

  • 謂詞
    在計算機語言中,謂詞通常指條件表達式的求值返回真或假的過程

1.一元謂詞(Unary Predicate)
一元謂詞通常用于判斷單個元素是否滿足某個條件,以下是一個使用std::remove_if和一元謂詞的簡單例子,它移除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() {
    // 初始化一個包含整數(shù)的 vector
    vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 使用 std::remove_if 和一元謂詞 isEven 移除所有偶數(shù)
    // std::remove_if 將所有滿足條件(即偶數(shù))的元素移動到 vector 的末尾,并返回新末尾的迭代器
    // vec.erase 則刪除從新末尾到原末尾的所有元素,從而實現(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)
二元謂詞通常用于比較兩個元素,以下是一個使用std::sort和二元謂詞的簡單例子,它根據(jù)自定義的比較規(guī)則對vector進行排序:

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

// 定義二元謂詞函數(shù),用于比較兩個整數(shù)的大小(降序排序)
// 參數(shù):
// - a: 第一個整數(shù)
// - b: 第二個整數(shù)
// 返回值:
// - 如果 a 大于 b,返回 true;否則返回 false
bool CompareInt(int a, int b) {
    return a > b;
}

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

    // 使用 std::sort 和二元謂詞 CompareInt 對 vector 進行降序排序
    // std::sort 接受三個參數(shù):起始迭代器、結束迭代器和比較函數(shù)
    // 比較函數(shù) CompareInt 確定了排序順序為降序
    std::sort(vec.begin(), vec.end(), CompareInt);

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

    return 0;
}

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

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

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

總結

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

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

相關文章

  • 詳解C++-二階構造模式、友元

    詳解C++-二階構造模式、友元

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

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

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

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

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

    C++封裝IATHOOK類實例

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

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

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

    C語言超詳細分析多進程的概念與使用

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

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

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

    C++ deque與vector對比的優(yōu)缺點

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

    C語言單鏈表實現(xiàn)學生管理系統(tǒng)

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

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

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

最新評論