【C++】C++11的包裝器:function與bind簡介

在這里插入圖片描述
各位大佬好,我是落羽!一個堅持不斷學習進步的學生。
如果您覺得我的文章還不錯,歡迎多多互三分享交流,一起學習進步!

也歡迎關注我的blog主頁: 落羽的落羽

文章目錄

  • 一、function
    • 1. 概念
    • 2. 用法
  • 二、bind
    • 1. 概念
    • 2. 用法

一、function

1. 概念

上一篇文章我們學習了lambda表達式的用法。

std::function是 C++11 標準庫在 <functional> 頭文件中引入的一個通用、多態的函數包裝器。它的本質是一個類模板,可以包裝、存儲、復制和調用任何可調用對象(函數指針、仿函數、lambda表達式、bind表達式等),存儲的可調用對象被稱為function的目標。function不含目標則為空,調用空function的目標會拋異常。
函數指針、仿函數、lambda表達式等可調用對象的類型各不相同,function可以統一類型,對他們進行包裝,這樣在很多地方就方便聲明可調用對象的類型。

2. 用法

在這里插入圖片描述
以上是function的原型,使用語法為:

#include <functional>
std::function<返回類型(參數類型1, 參數類型2, ...)> 包裝器名稱;

來看一段代碼實例:

#include <iostream>
#include <functional>
using namespace std;// 普通函數
int add(int a, int b) 
{return a + b;
}// Lambda表達式
auto multiply = [](int a, int b) { return a * b; };// 仿函數
struct Subtract 
{int operator()(int a, int b) const {return a - b;}
};int main() 
{// 聲明一個function,他可以包裝一個返回int,接受兩個int參數的可調用對象function<int(int, int)> func;// 包裝普通函數func = add;cout << "Add: " << func(10, 5) << endl; // 輸出 15// 包裝 Lambda 表達式func = multiply;cout << "Multiply: " << func(10, 5) << endl; // 輸出 50// 包裝仿函數對象Subtract sub;func = sub;cout << "Subtract: " << func(10, 5) << endl; // 輸出 5// 甚至可以包裝一個臨時的Lambdafunc = [](int a, int b) { return a / b; };cout << "Divide: " << func(10, 5) <<std::endl; // 輸出 2return 0;
}

有一個特殊的點是,類的成員函數也可以被包裝,但成員函數必須要指定類域并且前面加上&才能獲取地址,靜態成員函數可以不加&,但是為了方便記憶,建議成員函數都加上吧。這時還有一個問題,普通成員函數還有一個隱含的this指針,在類外包裝時,也一定要顯式寫出this指針參數類型,即當前類的指針類型:

class Plus
{
public:Plus(int n = 10):_n(n){}static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return (a + b) * _n;}private:int _n;
};int main()
{function<int(int, int)> f = &Plus::plusi;cout << f(1, 1) << endl; // 輸出2function<double(Plus*, double, double)> f1 = &Plus::plusd;//調用時實例化出一個對象取地址傳參即可,或者傳對象也可以Plus pdcout << f1(&pd, 1.1, 1.1) << endl; // 輸出22/*function<double(Plus, double, double)> f1 = &Plus::plusd;Plus pdcout << f1(pd, 1.1, 1.1) << endl; */return 0;
}

二、bind

1. 概念

std::bind是一個函數模板,也包含在<functional>中,是一個可調用對象的包裝器,可以把他看做一個函數適配器,對接收的可調用對象處理后返回一個可調用對象。bind可以用來調整參數個數和參數順序。
在這里插入圖片描述

2. 用法

調用bind的一般形式為:auto newCallable = bind(callable, arg_list);其中newCallable本身是一個可調用對象,arg_list是一個用逗號分隔的參數列表,對應給定callable的參數。arg_list中的參數可能包含形如_n的占位符,n是一個正整數,它們占據了傳遞給newCallable的參數的位置。n表示生成的可調用對象的參數的位置:如_1為newCallable的第1個參數,_2為newCallable的第2個參數,_3為newCallable的第3個參數,以此類推,_1/_2/_3…這些占位符都在一個叫placeholders的命名空間中。

#include <functional>
using namespace placeholders;int Sub(int a, int b)
{return a - b;
}int main()
{// _1代表sub1的第一個參數,_2代表sub1的第二個參數。// bind內寫成_2, _1的順序,意味sub1的第二個參數會傳給Sub的第一個參數a,sub1的第一個參數會傳給Sub的第二個參數bauto sub1 = bind(Sub, _2, _1);cout << Sub(1, 2) << endl; cout << sub1(1, 2) << endl;return 0;
}

在這里插入圖片描述
這是只改變參數順序的一般用法。

bind還有最常用的改變參數個數用法,這個用法一般是為了綁死某些參數,使之為一個固定值,使用時就不需要再傳參:

#include <functional>
using namespace placeholders;int Sub(int a, int b)
{return a - b;
}int main()
{// _1代表sub2的第一個參數,100代表綁死Sub的第一個參數a,a的值固定為100了// a的值固定了,傳參時就不需要傳給a,sub2的第一個參數就會傳給Sub的第二個參數bauto sub2 = bind(Sub, 100, _1);cout << Sub(1, 2) << endl;cout << sub2(1);return 0;
}

在這里插入圖片描述

再比如,剛才上面講到function包裝類成員函數時說到,使用包裝后的對象時還需要傳給this指針一個參數。有了bind就可以提前綁死這個參數,后續每次使用就不需要額外傳了:

#include <functional>
using namespace placeholders;class Plus
{
public:Plus(int n = 10):_n(n){}double plusd(double a, double b){return (a + b) * _n;}
private:int _n;
};int main()
{function<double(double, double)> f = bind(&Plus::plusd, Plus(), _1, _2);cout << f(1, 2) << endl;return 0;
}

在這里插入圖片描述

本篇完,感謝閱讀。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95853.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95853.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95853.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL高級特性詳解

MySQL高級特性詳解 一、自關聯查詢 概念 自關聯查詢是指一個表與它自己進行連接的查詢。通常用于處理具有層級關系或遞歸結構的數據。 應用場景 員工與上級關系分類的父子關系地區的層級關系 示例 -- 創建員工表 CREATE TABLE employees (emp_id INT PRIMARY KEY,emp_name VARC…

深度學習——調整學習率

學習率調整方法詳解在深度學習訓練過程中&#xff0c;學習率&#xff08;Learning Rate, LR&#xff09; 是影響模型收斂速度和效果的關鍵超參數。學習率過大可能導致訓練不穩定、震蕩甚至無法收斂&#xff1b;學習率過小又會導致收斂過慢甚至陷入局部最優。因此&#xff0c;如…

Java分頁 Element—UI

前端代碼 <div class"block"><span class"demonstration">頁數較少時的效果</span><el-paginationlayout"prev, pager, next":total"50"></el-pagination> </div>參考Element-UI total:0, form: …

html中列表和表格的使用

列表一般來說只有一列一列的進行使用&#xff0c;是一維的列表分為三種列表形式<!-- 列表標簽ul-li:無序列表&#xff0c;必須用 <ul> 當 “容器”&#xff08;代表 “無序列表”&#xff09;&#xff0c;每個條目用 <li> 包起來&#xff08;代表 “列表項”&am…

大學信息查詢平臺:一個現代化的React教育項目

一 項目簡介大學信息查詢平臺是一個基于React Vite Tailwind CSS構建的現代化Web應用&#xff0c;專門用于查詢中國各大高校的詳細信息。該項目不僅功能實用&#xff0c;更在用戶體驗和界面設計上做到了極致。二 核心功能2.1. 智能大學搜索// 搜索功能核心代碼 const searchU…

代碼隨想錄算法訓練營第六天 - 哈希表2 || 454.四數相加II / 383.贖金信 / 15.三數之和 / 18.四數之和

代碼隨想錄算法訓練營第六天 - 哈希表2 || 454.四數相加II / 383.贖金信 / 15.三數之和 / 18.四數之和454.四數相加II解題思路383.贖金信自己解答&#xff1a;代碼隨想錄講解暴力做法哈希表15.三數之和雙指針優化改進18.四數之和自己的解答系統講解454.四數相加II 文檔講解&…

FPGA實現流水式排序算法

該算法采用雙調排序算法&#xff0c;是一種可流水的遞推算法&#xff0c;且算法的消耗時長可算&#xff0c;具體細節參考視頻&#xff1a; https://www.bilibili.com/video/BV1S3thzWEnh/?spm_id_from333.1387.homepage.video_card.click&vd_source69fb997b62efa60ae1add…

平衡車 -- MPU6050

&#x1f308;個人主頁&#xff1a;羽晨同學 &#x1f4ab;個人格言:“成為自己未來的主人~” 傳感器原理 此外&#xff0c;用陀螺儀獲取x,y,z軸的加速度。 初始化 我們現在對MPU6050進行初始化&#xff0c;MPU6050通過I2C總線與單片機進行通信&#xff0c;通過的是PB8和PB…

在電路浪涌測試中,TVS(瞬態電壓抑制二極管)的防護效果確實會受到陪測設備中去耦網絡(Decoupling Network,DN)的顯著影響

在電路浪涌測試中&#xff0c;TVS&#xff08;瞬態電壓抑制二極管&#xff09;的防護效果確實會受到陪測設備中去耦網絡&#xff08;Decoupling Network&#xff0c;DN&#xff09;的顯著影響&#xff0c;這一現象與浪涌能量的傳遞路徑、阻抗匹配及信號完整性密切相關。結合 AD…

Redis之分布式鎖與緩存設計

1、分布式鎖 1.1、超賣問題/*** 存在庫存超賣的不安全問題*/private void deductStock() {int stockTotal Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));if (stockTotal > 0) { // 這里存在多個線程、進程同時判斷通過&#xff0c;然后超買…

靜態住宅IP的特點

穩定性高&#xff1a;與動態IP地址相比&#xff0c;靜態住宅IP不會不定時變更&#xff0c;能確保業務在網絡環境中的一致性和連貫性&#xff0c;適合需要長期維持同一身份的場景&#xff0c;如跨境電商業務等3。安全性強&#xff1a;由于其住宅屬性&#xff0c;看起來更像是正常…

Linux 編譯 Android 版 QGroundControl 軟件并運行到手機上

Linux 編譯 Android 版 QGroundControl 軟件并運行到手機上環境說明操作步驟一、參考上一篇文章在電腦端把環境搭建好二、配置 Qt Creator 的 Android 環境環境說明 電腦系統 Ubuntu 22.04 qgroundcontrol master 分支 Qt 6.8.3 操作步驟 一、參考上一篇文章在電腦端把環境搭…

Python 2025:量化金融與智能交易的新紀元

當Python遇見金融大數據&#xff0c;算法交易正迎來前所未有的技術變革在2025年的技術浪潮中&#xff0c;Python已經從一個"膠水語言"蛻變為金融科技領域的核心驅動力。根據GitHub 2025年度報告&#xff0c;Python在量化金融項目中的使用率增長了217%&#xff0c;在對…

[論文閱讀] 人工智能 + 軟件工程 | TDD痛點破解:LLM自動生成測試骨架靠譜嗎?靜態分析+專家評審給出答案

TDD痛點破解&#xff1a;LLM自動生成測試骨架靠譜嗎&#xff1f;靜態分析專家評審給出答案 論文信息項目詳情論文原標題Evaluation of Large Language Models for Generating RSpec Test Skeletons in Ruby on Rails論文鏈接https://arxiv.org/pdf/2509.04644一段話總結 該研究…

開源PSS解析器1

本章介紹另一個開源PSS解析工具zuspec&#xff1a; zuspec 提供了一組用于處理 actions relationship level 的工具 &#xff08;ARL&#xff09; 模型&#xff0c;主要是使用 Accellera 便攜式測試和刺激 &#xff08;PSS&#xff09; 語言描述的模型。ARL 模型用于為數字設計…

26考研——內存管理_內存管理策略(3)

408答疑 文章目錄一、內存管理策略1、內存管理的基本原理和要求1.1、相關概念1.2、邏輯地址與物理地址1.3、程序的鏈接與裝入1.4、進程的內存映像1.5、內存保護1.6、內存共享1.7、內存分配與回收1.8、在存儲管理中涉及到兩個問題2、連續分配管理方式2.1、相關概念2.2、單一連續…

Python爬蟲實戰:研究Event Handling機制,構建在線教育平臺的課程數據采集和分析系統

1. 引言 1.1 研究背景與意義 在大數據時代,互聯網作為全球最大的信息載體,蘊含著海量有價值的數據。這些數據涵蓋了商業交易、用戶行為、社會趨勢等多個領域,對企業決策、學術研究和社會管理具有重要參考價值。如何高效、準確地獲取這些數據并進行深度分析,成為當前數據科…

docker 安裝 redis 并設置 volumes 并修改 修改密碼(四)

設置新密碼: 127.0.0.1:6379> CONFIG SET requirepass newpassword OK驗證新密碼: 127.0.0.1:6379> AUTH newpassword OK更新配置文件: 編輯主機的配置文件/data/redis/conf/redis.conf,將requirepass的值修改為新密碼: requirepass newpassword重啟容器以使配置…

NBA球星知識大挑戰:基于 PyQt5 的球星認識小游戲

NBA球星知識大挑戰&#xff1a;基于 PyQt5 的球星認識小游戲 代碼詳見&#xff1a;https://github.com/xiaozhou-alt/NBA_Players_Recognition 文章目錄 NBA球星知識大挑戰&#xff1a;基于 PyQt5 的球星認識小游戲一、項目介紹二、文件夾結構三、項目實現1. 自定義動畫按鈕&a…

電磁波成像(X射線、CT成像)原理簡介

電磁波成像&#xff08;X射線、CT成像&#xff09;原理簡介一、圖像形成的一般形式二、可見光成像2.1可見光2.2可見光成像三、其他電磁波成像3.1X射線成像3.2CT成像3.2.1CT成像原理3.2.2CT成像與X射線成像對比3.2.3CT生成三維描述3.3PET成像一、圖像形成的一般形式 大多數圖像…