1.std:bind
std:bind是一個函式模板,可以用來系結一切函式
1.1 系結普通成員函式,普通靜態成員函式,普通模板函式
例子:
#include <functional>
#include <iostream>
#include <cstdio>
void fun(int a, int b)
{
std::cout <<a+b<<std::endl;
}
int main()
{
auto funBind = std::bind(fun, 4, 6);
funBind();
return 0;
}
結果為
10
上面的例子中函式fun被系結到了funBind中,fun中的引數被系結到了一個固定的值,當然你也可以不指定它的值,在系結值時給它一個預設值,即系結到占位符(std::placeholders)上,如下:
#include <functional>
#include <iostream>
#include <cstdio>
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
//系結到靜態函式
static void staticfun(int a, int b)
{
std::cout << a + b << std::endl;
}
//系結到模板函式
template<typename A, typename B>
inline void addFun(A a, B b)
{
std::cout << a + b << std::endl;
}
int main()
{
auto funBind = std::bind(fun, std::placeholders::_1, 6);
funBind(4);
auto funBind1 = std::bind(staticfun, std::placeholders::_1, std::placeholders::_2);
funBind1(5, 6);
auto funBind2 = std::bind(addFun<int,int>, std::placeholders::_1, std::placeholders::_2);
funBind2(6, 6);
return 0;
}
結果:
10
11
12
需要注意的是:系結到模板函式的時候,第一個引數需要指定引數的型別
1.2 系結類成員函式,類靜態成員函式,類模板函式
需要注意的是:在系結類成員函式時,bind的第一個引數為物件的成員函式指標,第二個引數為一個具體的物件實體指標,如下
#include <functional>
#include <iostream>
#include <cstdio>
class S {
public:
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
//系結到靜態函式
static void staticfun(int a, int b)
{
std::cout << a + b << std::endl;
}
template<typename A, typename B>
inline void addFun(A a, B b)
{
std::cout << a + b << std::endl;
}
};
int main()
{
S s;
auto funBind = std::bind(&S::fun,&s,std::placeholders::_1, 6);
funBind(4);
auto funBind1 = std::bind(&S::staticfun, std::placeholders::_1, std::placeholders::_2);
funBind1(5,6);
auto funBind2 = std::bind(&S::addFun<int,int>, &s,std::placeholders::_1, std::placeholders::_2);
funBind2(6, 6);
return 0;
}
結果:
10
11
12
需要注意的是成員函式的訪問權限為public,在系結靜態成員函式時,第二個引數不需要指定具體物件實體的地址
1.3 系結參考引數
先看例子:
#include <functional>
#include <iostream>
#include <cstdio>
int add(int& a, const int& b)
{
return a+b;
}
int main()
{
int a = 2, b = 4;
auto funcBind = std::bind(add, std::ref(a), std::cref(b));
std::cout << funcBind() << std::endl;
return 0;
}
```c
結果為:
```c
6
在上面的例子a為普通參考,在系結傳遞值時呼叫ref即可,而b為常量參考,在系結傳遞值時呼叫cref即可
1.4 系結lambda運算式
#include <functional>
#include <iostream>
#include <cstdio>
auto lambda = [](int a, int b)
{
return a + b;
};
int main()
{
int a = 2, b = 4;
auto funcBind = std::bind(lambda, a, b);
std::cout << funcBind() << std::endl;
return 0;
}
結果:
6
2.std::function
2.1 封裝普通函式/靜態函式/lambda運算式
std::function是一個函式模板類,是一個類,定義在頭檔案可以用其定義不同的物件,物件的型別可以是普通函式,靜態函式以及Lambda運算式,在不用std::function之前,定義一個函式指標通常用以下方法定義,如:
typedef void (*funPtr)(int,int);
使用std::function之后,這樣定義
std::function<void(int ,int)> funPtr;
通常這樣子使用,先定義一個函式,再將這個函式指標賦值給一個std::function物件,如下
#include <functional>
#include <iostream>
#include <cstdio>
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
static void fun1(int a, int b)
{
std::cout << a + b << std::endl;
}
auto lambda = [](int a, int b)
{
std::cout << a + b << std::endl;
};
int main()
{
std::function<void(int, int)> funPtr = fun;
funPtr(1, 2);
std::function<void(int, int)> funPtr1 = fun1;
funPtr1(2, 2);
std::function<void(int, int)> funPtr2 = lambda;
funPtr2(3, 2);
return 0;
}
結果:
3
4
5
2.2 系結成員函式/靜態成員函式/函式模板/成員變數
在封裝成員函式/靜態成員函式時,std::function和std::bind搭配使用
#include <functional>
#include <iostream>
#include <cstdio>
class S {
public:
int num;
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
//系結到靜態函式
static void staticfun(int a, int b)
{
std::cout << a + b << std::endl;
}
template<typename A, typename B>
inline void addFun(A a, B b)
{
std::cout << a + b << std::endl;
}
};
int main()
{
S s;
//錯誤的,不可以使用 std::function指向類的非靜態成員
//std::function<void(int, int)> funBind = std::bind(&S::fun, &s, std::placeholders::_1, 6);
//funBind(4);
std::function<void(int, int)> funBind1 = std::bind(&S::staticfun, std::placeholders::_1, std::placeholders::_2);
funBind1(5, 6);
std::function<void(int, int)> funBind2 = std::bind(&S::addFun<int, int>, &s, std::placeholders::_1, std::placeholders::_2);
funBind2(6, 6);
//系結成員變數
std::function<int& ()> MyValue = std::bind(&S::num, &s);
MyValue() = 1000;//相當于s.num=1000
std::cout << "num = "<<s.num<< std::endl;
return 0;
}
結果:
11
12
num = 1000
需要注意的是不可以使用 std::function指向類的非靜態成員,可以用函式指標的形式表示或者在類中直接系結,如下:
#include <iostream>
#include <vector>
#include <functional>
class Father
{
public:
void Called() {
for (int i = 0; i < Vec.size(); i++)
Vec[i]();
}
protected:
std::vector<std::function<void()>> Vec;
};
class Son : public Father
{
public:
Son()
{
std::function<void()> fun1 = std::bind(&Son::A, this);
std::function<void()> fun2 = std::bind(&Son::B, this);
Vec.push_back(fun1);
Vec.push_back(fun2);
}
private:
void A() { std::cout << "A\n"; }
void B() { std::cout << "B\n"; }
};
int main()
{
Son d;
d.Called();
return 0;
}
結果:
A
B
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/338203.html
標籤:其他
