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

C++中function包裝器的應(yīng)用實(shí)例詳解

 更新時(shí)間:2024年12月31日 08:55:00   作者:藤椒味的火腿腸真不錯(cuò)  
這篇文章主要介紹了C++中function包裝器的相關(guān)資料,std::function是C++11引入的一個(gè)模板類,用于封裝任何可調(diào)用對(duì)象,使得函數(shù)能夠像對(duì)象一樣傳遞、存儲(chǔ)和調(diào)用,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言:

在現(xiàn)代 C++ 中,std::function 是一個(gè)非常有用的工具,它使得函數(shù)能夠像對(duì)象一樣傳遞、存儲(chǔ)和調(diào)用。隨著 C++11 的到來,std::function 被引入到標(biāo)準(zhǔn)庫(kù)中,成為函數(shù)式編程和回調(diào)機(jī)制的核心組件之一。在這篇博客中,我們將深入探討 std::function 的工作原理、應(yīng)用場(chǎng)景及其優(yōu)缺點(diǎn)。

 1.什么是 std::function?

std::function 是 C++11 引入的一個(gè)模板類,用于封裝任何可調(diào)用對(duì)象如普通函數(shù)、Lambda 表達(dá)式、函數(shù)指針、成員函數(shù)指針或函數(shù)對(duì)象等)。它允許你存儲(chǔ)一個(gè)可調(diào)用對(duì)象,并在需要時(shí)調(diào)用它。這使得我們可以更加靈活地編寫代碼,特別是在需要傳遞回調(diào)函數(shù)或異步任務(wù)時(shí),std::function 顯得尤為重要。

std::function 是通過類型擦除實(shí)現(xiàn)的,它可以在運(yùn)行時(shí)動(dòng)態(tài)地將不同類型的可調(diào)用對(duì)象轉(zhuǎn)化為統(tǒng)一的接口。簡(jiǎn)單來說,它允許你用一個(gè)通用的對(duì)象來代替不同類型的函數(shù)或函數(shù)指針。

2. function 包裝器的原型

std::function在頭文件<functional>

// 類模板原型如下

template <class T> function; // undefined

template <class Ret, class... Args>

class function<Ret(Args...)>;

模板參數(shù)說明:

Ret: 被調(diào)用函數(shù)的返回類型Args…:被調(diào)用函數(shù)的形參。

 3.使用 function 封裝不同類型的函數(shù)對(duì)象

#include <iostream>
#include <functional>
#include <string>

using namespace std;

// 普通函數(shù)
void func(int n)
{
    cout << "普通函數(shù): " << n << endl;
}

// 仿函數(shù)
struct Func
{
    void operator()(int n)
    {
        cout << "仿函數(shù): " << n << endl;
    }
};

// Lambda 表達(dá)式
auto lambda = [](int n) { cout << "Lambda 表達(dá)式: " << n << endl; };

int main()
{
    // 使用 std::function 封裝不同類型的函數(shù)
    function<void(int)> f;

    f = func;           // 包裝普通函數(shù)
    f(10);

    f = Func();         // 包裝仿函數(shù)
    f(20);

    f = lambda;         // 包裝 Lambda 表達(dá)式
    f(30);

    return 0;
}

代碼分析

我們定義了三個(gè)不同類型的函數(shù):一個(gè)普通函數(shù) func、一個(gè)仿函數(shù) Func 和一個(gè) Lambda 表達(dá)式 lambda。

然后,使用 std::function<void(int)> 來封裝這三種不同類型的函數(shù)對(duì)象。

通過調(diào)用包裝后的 f,我們可以統(tǒng)一的方式執(zhí)行這些不同的函數(shù)對(duì)象。(適配器)

這種方式使得我們能夠?qū)⒍喾N類型的可調(diào)用對(duì)象統(tǒng)一為一個(gè)接口,方便管理和使用。

4.實(shí)際應(yīng)用:

 150. 逆波蘭表達(dá)式求值 - 力扣(LeetCode)

 解法一:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
      stack<int> st;
      for(auto& to:tokens)
      {
        if(to=="+"||to=="-"||to=="*"||to=="/")
        {
            int right=st.top();
            st.pop();

            int left=st.top();
            st.pop();
           switch(to[0])
           {
            case '+':
            st.push(left+right);
            break;
            
            case '-':
            st.push(left-right);
            break;

            case '*':
            st.push(left*right);
            break;
           
            case '/':
            st.push(left/right);
            break;
           }
        }
        else
        {
            st.push(stoi(to));
        }
      }
    return st.top();
    }
};

解法二: 利用function包裝器:

class Solution 
{
public:
    int evalRPN(vector<string>& tokens) 
    {
        // 解題思路:操作數(shù)入棧,遇到操作符,取兩個(gè)數(shù)計(jì)算后,入棧

        // 建立映射關(guān)系
        unordered_map<string, function<int(int, int)>> hash = 
        {
            {"+", [](int x, int y)->int { return x + y; } },
            {"-", [](int x, int y)->int { return x - y; } },
            {"*", [](int x, int y)->int { return x * y; } },
            {"/", [](int x, int y)->int { return x / y; } },
        };

        stack<int> s;

        for(auto str : tokens)
        {
            if(str != "+" && str != "-" && str != "*" && str != "/")
                s.push(stoi(str));
            else
            {
                // 注意:先獲取 y,再獲取 x
                int y = s.top();
                s.pop();
                int x = s.top();
                s.pop();

                s.push(hash[str](x, y));
            }
        }

        return s.top();
    }
};

function作為C++11的一個(gè)知識(shí),還是非常好用的。??

 5. bind 綁定:修改參數(shù)傳遞順序和數(shù)量

bind 是 C++ 標(biāo)準(zhǔn)庫(kù)中的一個(gè)函數(shù)模板,它允許我們對(duì)函數(shù)參數(shù)進(jìn)行預(yù)先綁定或重新排列,從而生成一個(gè)新的可調(diào)用對(duì)象。bind 的強(qiáng)大之處在于,它不僅能夠指定某些參數(shù)的固定值,還能改變參數(shù)傳遞的順序,極大地提高了靈活性。

函數(shù)原型:

template <class Fn, class... Args>
bind (Fn&& fn, Args&&... args);

 fn 是傳遞的 函數(shù)對(duì)象,args 是傳給函數(shù)的 可變參數(shù)包,這里使用了 萬能引用(引用折疊),使其在進(jìn)行模板類型推導(dǎo)時(shí),既能引用左值,也能引用右值。

2.1 使用 bind 綁定修改參數(shù)傳遞順序

#include <iostream>
#include <functional>

using namespace std;

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

int main()
{
    // 正常調(diào)用
    Func(10, 20);

    // 使用 bind 改變參數(shù)順序
    auto RFunc = bind(Func, std::placeholders::_2, std::placeholders::_1);
    RFunc(10, 20);  // 輸出: Func: 20 10

    return 0;
}

代碼分析

bind(Func, std::placeholders::_2, std::placeholders::_1) 通過 placeholders::_1 和 placeholders::_2 指定了新的參數(shù)順序,即將原本的第二個(gè)參數(shù)和第一個(gè)參數(shù)交換。

當(dāng)我們調(diào)用 RFunc(10, 20) 時(shí),實(shí)際上是將 20 作為第一個(gè)參數(shù),10 作為第二個(gè)參數(shù)傳遞給 Func。

這種參數(shù)順序的改變,在一些特定的應(yīng)用場(chǎng)景下非常有用,特別是在函數(shù)簽名不一致時(shí),可以方便地進(jìn)行適配。

2.2. bind 綁定:指定特定參數(shù)

bind 還可以用于指定函數(shù)的某些參數(shù)為固定值,從而減少后續(xù)調(diào)用時(shí)需要傳遞的參數(shù)個(gè)數(shù)。

示例代碼:使用 bind 綁定指定特定參數(shù)

#include <iostream>
#include <functional>

using namespace std;

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

int main()
{
    // 使用 bind 綁定第一個(gè)參數(shù)
    auto RFunc = bind(Func, 100, std::placeholders::_1);
    RFunc(20);  // 輸出: Func: 100 20

    return 0;
}

代碼分析

我們通過 bind(Func, 100, std::placeholders::_1) 將第一個(gè)參數(shù)綁定為固定值 100

后續(xù)調(diào)用時(shí),我們只需要傳遞第二個(gè)參數(shù) 20,bind 會(huì)自動(dòng)將 100 作為第一個(gè)參數(shù)傳遞給 Func

2.3. bind 綁定與類成員函數(shù)

bind 還可以用于綁定類成員函數(shù)。對(duì)于普通函數(shù),綁定非常簡(jiǎn)單,但對(duì)于成員函數(shù),我們需要額外注意如何傳遞類的對(duì)象或指針。

示例代碼:使用 bind 綁定靜態(tài)成員函數(shù)

#include <iostream>
#include <functional>

using namespace std;

class Test
{
public:
    static void funcA(int val)
    {
        cout << "靜態(tài)成員函數(shù) funcA: " << val << endl;
    }
};

int main()
{
    // 使用 bind 綁定靜態(tài)成員函數(shù)
    auto RFunc = bind(&Test::funcA, std::placeholders::_1);
    RFunc(10);  // 輸出: 靜態(tài)成員函數(shù) funcA: 10

    return 0;
}

代碼分析

對(duì)于靜態(tài)成員函數(shù),我們可以直接使用 &Test::funcA 來綁定。

bind 會(huì)自動(dòng)處理函數(shù)的綁定,并返回一個(gè)新的可調(diào)用對(duì)象 RFunc我們可以使用它來調(diào)用函數(shù)。

 示例代碼:使用 bind 綁定非靜態(tài)成員函數(shù)

#include <iostream>
#include <functional>

using namespace std;

class Test
{
public:
    Test(int n) : _n(n) {}

    void funcB(int val)
    {
        cout << "非靜態(tài)成員函數(shù) funcB: " << val * _n << endl;
    }

private:
    int _n;
};

int main()
{
    Test t(10);
    // 使用 bind 綁定非靜態(tài)成員函數(shù)
    auto RFunc = bind(&Test::funcB, t, std::placeholders::_1);
    RFunc(5);  // 輸出: 非靜態(tài)成員函數(shù) funcB: 50

    return 0;
}

 代碼分析

對(duì)于非靜態(tài)成員函數(shù),我們需要提供類的對(duì)象 t 作為參數(shù)來綁定。

bind 會(huì)將 t 與 &Test::funcB 結(jié)合,并生成一個(gè)新的可調(diào)用對(duì)象。

總結(jié):

通過 std::function 和 bind,C++ 提供了強(qiáng)大的函數(shù)包裝和綁定功能,使得我們能夠在不同類型的函數(shù)之間進(jìn)行無縫切換、修改參數(shù)傳遞順序以及綁定特定參數(shù)。這些工具極大地增強(qiáng)了代碼的靈活性和可重用性,特別是在需要對(duì)多個(gè)不同函數(shù)進(jìn)行統(tǒng)一管理時(shí),它們提供了非常便捷的解決方案。在實(shí)際開發(fā)中,這些技巧不僅能幫助我們提升編程效率,還能讓代碼更加簡(jiǎn)潔和優(yōu)雅。

到此這篇關(guān)于C++中function包裝器應(yīng)用的文章就介紹到這了,更多相關(guān)C++ function包裝器應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文搞懂C++ 動(dòng)態(tài)內(nèi)存

    一文搞懂C++ 動(dòng)態(tài)內(nèi)存

    這篇文章主要介紹了C++ 動(dòng)態(tài)內(nèi)存的的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • vector,map,list,queue的區(qū)別詳細(xì)解析

    vector,map,list,queue的區(qū)別詳細(xì)解析

    如果我們需要隨機(jī)訪問一個(gè)容器則vector要比list好得多。如果我們已知要存儲(chǔ)元素的個(gè)數(shù)則vector 又是一個(gè)比list好的選擇。如果我們需要的不只是在容器兩端插入和刪除元素則list顯然要比vector好
    2013-09-09
  • C++程序中啟動(dòng)線程的方法

    C++程序中啟動(dòng)線程的方法

    這篇文章主要介紹了C++程序中啟動(dòng)線程的方法,作者針對(duì)C++11版本中的一些新特性進(jìn)行了解說,需要的朋友可以參考下
    2015-07-07
  • 一文詳細(xì)講解C++精妙的哈希算法

    一文詳細(xì)講解C++精妙的哈希算法

    這篇文章主要介紹了C++精妙的哈希算法的相關(guān)資料,哈希結(jié)構(gòu)通過哈希函數(shù)將關(guān)鍵碼映射到表中的特定位置,以提高搜索效率,理想的哈希函數(shù)應(yīng)保證一致性、哈希值均勻分布、高計(jì)算效率與最小化沖突,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • C++編程中私有和保護(hù)以及公有的類成員訪問控制

    C++編程中私有和保護(hù)以及公有的類成員訪問控制

    這篇文章主要介紹了C++編程中私有和保護(hù)以及公有的類成員訪問控制,即private和protected以及public關(guān)鍵字的相關(guān)作用和用法,需要的朋友可以參考下
    2016-01-01
  • 用C語言實(shí)現(xiàn)2048游戲

    用C語言實(shí)現(xiàn)2048游戲

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)2048游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C/C++中使用列表框組件Qt?ListWidget

    C/C++中使用列表框組件Qt?ListWidget

    本文詳細(xì)講解了C/C++中使用列表框組件Qt?ListWidget的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • C++之智能指針初步及棄用auto_ptr的原因分析

    C++之智能指針初步及棄用auto_ptr的原因分析

    這篇文章主要介紹了C++之智能指針初步及棄用auto_ptr的原因分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • C++獲取GPU顯卡信息的示例代碼

    C++獲取GPU顯卡信息的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用C++獲取GPU顯卡信息,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-02-02
  • 枚舉類型的定義和應(yīng)用總結(jié)

    枚舉類型的定義和應(yīng)用總結(jié)

    如果一種變量只有幾種可能的值,可以定義為枚舉類型。所謂“枚舉類型”是將變量的值一一列舉出來,變量的值只能在列舉出來的值的范圍內(nèi)
    2013-10-10

最新評(píng)論

漯河市| 乐清市| 屏山县| 横峰县| 麻江县| 普格县| 淮阳县| 博湖县| 汶川县| 林口县| 外汇| 平顶山市| 玉屏| 宿松县| 宁蒗| 邢台市| 罗山县| 镇坪县| 长葛市| 新兴县| 雷州市| 定结县| 内丘县| 天台县| 大丰市| 嘉祥县| 阿勒泰市| 龙井市| 霍山县| 浏阳市| 尼勒克县| 呼伦贝尔市| 兰考县| 马鞍山市| 清新县| 临海市| 方正县| 景洪市| 桂林市| 迁西县| 平利县|