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

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

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

前言:

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

 1.什么是 std::function?

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

std::function 是通過類型擦除實現(xiàn)的,它可以在運行時動態(tài)地將不同類型的可調(diào)用對象轉(zhuǎn)化為統(tǒng)一的接口。簡單來說,它允許你用一個通用的對象來代替不同類型的函數(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ù)對象

#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 表達式
auto lambda = [](int n) { cout << "Lambda 表達式: " << n << endl; };

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

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

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

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

    return 0;
}

代碼分析

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

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

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

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

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

 150. 逆波蘭表達式求值 - 力扣(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ù)入棧,遇到操作符,取兩個數(shù)計算后,入棧

        // 建立映射關(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的一個知識,還是非常好用的。??

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

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

函數(shù)原型:

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

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

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ù)順序,即將原本的第二個參數(shù)和第一個參數(shù)交換。

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

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

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

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

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

#include <iostream>
#include <functional>

using namespace std;

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

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

    return 0;
}

代碼分析

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

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

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

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

示例代碼:使用 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;
}

代碼分析

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

bind 會自動處理函數(shù)的綁定,并返回一個新的可調(diào)用對象 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;
}

 代碼分析

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

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

總結(jié):

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

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

相關(guān)文章

  • 利用C語言實現(xiàn)猜數(shù)字小游戲

    利用C語言實現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了利用C語言實現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C語言遞歸操作用法總結(jié)

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

    這篇文章主要介紹了C語言遞歸操作用法,結(jié)合實例形式總結(jié)分析了C語言遞歸操作的原理、實現(xiàn)技巧與相關(guān)應(yīng)用,需要的朋友可以參考下
    2016-02-02
  • 基于QT實現(xiàn)文件上傳和下載功能

    基于QT實現(xiàn)文件上傳和下載功能

    這篇文章主要為大家詳細(xì)介紹了基于QT實現(xiàn)文件上傳和下載功能,支持?jǐn)帱c續(xù)傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 深入解析C++中的字符數(shù)組和處理字符串的方法

    深入解析C++中的字符數(shù)組和處理字符串的方法

    這篇文章主要介紹了深入解析C++中的字符數(shù)組和處理字符串的方法,需要的朋友可以參考下
    2015-09-09
  • c++中臨時變量不能作為非const的引用參數(shù)的方法

    c++中臨時變量不能作為非const的引用參數(shù)的方法

    下面小編就為大家?guī)硪黄猚++中臨時變量不能作為非const的引用參數(shù)的方法。小編覺得挺不錯的現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • C++三色球問題描述與算法分析

    C++三色球問題描述與算法分析

    這篇文章主要介紹了C++三色球問題描述與算法分析,結(jié)合注釋形式詳細(xì)講述了三色球問題的描述與相應(yīng)的算法設(shè)計思路,并給出了相關(guān)的實現(xiàn)方法,需要的朋友可以參考下
    2016-05-05
  • C++計算圓形、矩形和三角形的面積

    C++計算圓形、矩形和三角形的面積

    這篇文章介紹了C++計算圓形、矩形和三角形面積的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • 詳解C++中typedef 和 #define 的區(qū)別

    詳解C++中typedef 和 #define 的區(qū)別

    這篇文章主要介紹了C++中typedef 與 #define 的區(qū)別,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • C語言算法練習(xí)之佩奇存錢方案

    C語言算法練習(xí)之佩奇存錢方案

    這篇文章主要該大家分享C語言算法佩奇存錢的練習(xí),文章主要通過描述佩奇存錢的問題然后確定程序框架將結(jié)果運算出來,下面來看詳細(xì)內(nèi)容吧,需要的朋友可以參考一下
    2022-04-04
  • C++線程同步實例分析

    C++線程同步實例分析

    這篇文章主要介紹了C++線程同步實例分析,以實例的形式較為深入的分析了C++的線程同步問題,是一個較為經(jīng)典的線程同步問題,需要的朋友可以參考下
    2014-10-10

最新評論