bind 是什麼?
bind 顧名思義: 繫結
通俗來講呢,可以這麼理解有點像函式指標的意思。
資料上是這麼講的:可以將 bind 函式看做一個通用函式的介面卡,它接受一個可呼叫物件,生成一個新的可以呼叫物件來“適應”原物件引數列表
它一般呼叫形式:
// 其中 newCallable 是一個可呼叫的物件, arg_list 是以逗號分隔的引數列表
// 這時我們呼叫 newCallable,newCallable 就會呼叫 callable, 並用 arg_list 傳遞引數
auto newCallable = bind(callable, arg_list);
好了,重點在於 arg_list 裡,那麼我們如何傳入引數呢
它們是靠這些引數的位置來識別的,形如 _n 之類的, n 是整形, _1 是第一個引數,_2是第二個引數,以此類推。
而名字 _n 是定義在 placeholders 名稱空間中, 而 placeholders 本身又定義在 std 名稱空間中, 所以形如:
using std:: placeholders::_1
接下來,我們舉例幾個列子
舉個例子
bind 是在標頭檔案 #include <functional>
中, 首先要包含它。
1. bind 無引數的普通函式
#include <iostream>
#include <functional> // 包含此標頭檔案
// 普通函式
void Fun()
{
std::cout << "I am Fun!" << std::endl;
}
// 主函式
int main()
{
auto fun = std::bind(Fun); // 適配 Fun 函式並返回一個可呼叫的物件
fun();
return 0;
}
除錯結果:
2. bind 1個引數的普通函式
#include <iostream>
#include <functional> // 包含此標頭檔案
// 普通函式
void Fun(int a)
{
std::cout << "I am Fun! a = " << a <<std::endl;
}
// 主函式
int main()
{
auto fun = std::bind(Fun, std::placeholders::_1);
fun(5);
return 0;
}
除錯結果:
3. bind 多個引數的普通函式
#include <iostream>
#include <functional> // 包含此標頭檔案
// 普通函式
int Fun(int a, int b)
{
return a - b;
}
// 主函式
int main()
{
auto fun = std::bind(Fun, std::placeholders::_1, std::placeholders::_2);
std::cout << fun(5, 2) << std::endl;
return 0;
}
除錯結果:
4. bind 多個引數的普通函式並打亂引數位置
#include <iostream>
#include <functional> // 包含此標頭檔案
// 普通函式
int Fun(int a, int b)
{
return a - b;
}
// 主函式
int main()
{
auto fun1 = std::bind(Fun, std::placeholders::_1, std::placeholders::_2);
auto fun2 = std::bind(Fun, std::placeholders::_2, std::placeholders::_1);
std::cout << fun1(5, 2) << std::endl;
std::cout << fun2(5, 2) << std::endl;
return 0;
}
除錯結果:
5. bind 類的成員函式
#include <iostream>
#include <functional> // 包含此標頭檔案
class MyClass {
public:
MyClass() {}
~MyClass() {}
public:
void printInfo() {
std::cout << "MyClass Info." << std::endl;
}
};
// 主函式
int main()
{
MyClass A;
auto fun = std::bind(&MyClass::printInfo, A);
fun();
return 0;
}
除錯結果:
再舉個應用栗子
#include <iostream>
#include <functional> // 包含此標頭檔案
typedef std::function<void(int)> CallbackType;
// A 類
class MyClassA {
public:
void regeditCallBack(CallbackType fun)
{ _callback_fun = fun; }
void printInfoA(int d)
{ _callback_fun(d); }
private:
CallbackType _callback_fun;
};
// B 類
class MyClassB {
public:
void printInfoB(int d) {
std::cout << d << std::endl;
}
};
// 主函式
int main()
{
MyClassB B;
auto funB = std::bind(&MyClassB::printInfoB, B, std::placeholders::_1);
MyClassA A;
A.regeditCallBack(funB);
A.printInfoA(1);
return 0;
}
除錯結果:
結束
學無止境