1 std::bind
template <class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);
template <class Ret, class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);
1.1 函数模板说明
- 基于参数f返回一个函数对象,并且以args参数绑定为函数对象的参数。
- 每个参数要么绑定一个参数值,要么绑定为一个std::placeholders。
- 如果参数绑定成一个值,那么返回的函数对象将总使用绑定的参数值做为调用参数,即调用传入参数将不起作用;如果参数绑定为std::placeholders,那么返回的函数对象在被调用时需要传入实时参数,参数填充的位置即由placeholder指定的序号。
1.2 函数模板参数说明
- f : 可调用的函数对象,比如函数对象、函数指针、函数引用、成员函数或者数据成员函数
- args - 需要绑定的函数的参数列表,使用命名空间占位符std::placeholders::_1,std::placeholders::_2标志参数,其中std::placeholders::_1标志为参数列表中的第一个参数,std::placeholders::_2标志参数列表中的第二个参数,std::placeholders::_3标志参数列表中的第三个参数,以此类推。
1.3 函数模板返回值说明
返回一个函数对象,该函数在调用时使用参数列表args来调用f。如果f是指向类的成员函数,则返回函数第一个参数应该是该类的成员、或者成员对象的引用、或者是成员对象的指针。
2 std::bind可绑定的几种函数形式总结
2.1 绑定普通函数或者静态函数
2.1.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
using namespace std::placeholders;
void StaticBindFunc(int a, int b)
{
std::cout << "静态函数被调用,a =" << a << ",b=" << b << std::endl;
}
int main()
{
// 1 使用占位符先占位,然后执行时再传参
auto staticFunc1 = std::bind(&StaticBindFunc, std::placeholders::_1, std::placeholders::_2);
staticFunc1(1,2);
// 2 使用一个占位符先占位,然后执行时传一个参
auto staticFunc2 = std::bind(&StaticBindFunc, std::placeholders::_1, 4);
staticFunc2(3);
auto staticFunc3 = std::bind(&StaticBindFunc, 5, std::placeholders::_1);
staticFunc3(6);
// 3 使用占位符先占位,但是参数位置调换
auto staticFunc4 = std::bind(&StaticBindFunc, std::placeholders::_2, std::placeholders::_1);
staticFunc4(7,8);
getchar();
return 0;
}
2.1.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
using namespace std::placeholders;
template <class T>
void StaticBindFunc(T a, T b)
{
std::cout << "静态函数被调用,a =" << a << ",b=" << b << std::endl;
}
int main()
{
// 1 使用占位符先占位,然后执行时再传参
auto staticFunc1 = std::bind(&StaticBindFunc<int>, std::placeholders::_1, std::placeholders::_2);
staticFunc1(1, 2);
// 2 使用一个占位符先占位,然后执行时传一个参
auto staticFunc2 = std::bind(&StaticBindFunc<int>, std::placeholders::_1, 4);
staticFunc2(3);
auto staticFunc3 = std::bind(&StaticBindFunc<int>, 5, std::placeholders::_1);
staticFunc3(6);
// 3 使用占位符先占位,但是参数位置调换
auto staticFunc4 = std::bind(&StaticBindFunc<int>, std::placeholders::_2, std::placeholders::_1);
staticFunc4(7, 8);
getchar();
return 0;
}
2.2 绑定类的成员函数
2.2.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
void Add(int a, int b)
{
std::cout << "类的成员函数被调用,a =" << a << ",b=" << b << std::endl;
}
};
int main()
{
// 1 类的对象
A tempA;
auto memberFunc1 = std::bind(&A::Add, tempA, std::placeholders::_1, std::placeholders::_2);
memberFunc1(1, 2);
// 2 类的对象的引用
auto memberFunc2 = std::bind(&A::Add, &tempA, std::placeholders::_1, std::placeholders::_2);
memberFunc2(3, 4);
// 3 类的对象的指针
A* pTempA = new A();
auto memberFunc3 = std::bind(&A::Add, pTempA, std::placeholders::_1, std::placeholders::_2);
memberFunc3(5, 6);
delete pTempA;
// 4 类的对象的智能指针
A::ptr pTempAPtr = std::make_shared<A>();
auto memberFunc4 = std::bind(&A::Add, pTempAPtr, std::placeholders::_1, std::placeholders::_2);
memberFunc4(7, 8);
getchar();
return 0;
}
2.2.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
template <class T>
void Add(T a, T b)
{
std::cout << "类的成员函数被调用,a =" << a << ",b=" << b << std::endl;
}
};
int main()
{
// 1 类的对象
A tempA;
auto memberFunc1 = std::bind(&A::Add<int>, tempA, std::placeholders::_1, std::placeholders::_2);
memberFunc1(1, 2);
// 2 类的对象的引用
auto memberFunc2 = std::bind(&A::Add<int>, &tempA, std::placeholders::_1, std::placeholders::_2);
memberFunc2(3, 4);
// 3 类的对象的指针
A* pTempA = new A();
auto memberFunc3 = std::bind(&A::Add<int>, pTempA, std::placeholders::_1, std::placeholders::_2);
memberFunc3(5, 6);
delete pTempA;
// 4 类的对象的智能指针
A::ptr pTempAPtr = std::make_shared<A>();
auto memberFunc4 = std::bind(&A::Add<int>, pTempAPtr, std::placeholders::_1, std::placeholders::_2);
memberFunc4(7, 8);
getchar();
return 0;
}
2.3 绑定类的公有成员变量
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
int m_Value = 20;
};
int main()
{
// 绑定类公共成员变量,不可绑定私有成员变量
auto memberVar = std::bind(&A::m_Value, std::placeholders::_1);
// 1 类对象做参数传递
A tempA;
std::cout << memberVar(tempA) <<std::endl;
// 2 类对象引用做参数传递
std::cout << memberVar(&tempA) << std::endl;
// 3 类指针做参数传递
A* pTempA = new A();
std::cout << memberVar(pTempA) << std::endl;
delete pTempA;
// 4 类智能指针做参数传递
A::ptr pTempAPtr = std::make_shared<A>();
std::cout << memberVar(pTempAPtr) << std::endl;
std::cout << memberVar(std::make_shared<A>()) << std::endl;
getchar();
return 0;
}
2.4 绑定lambda表达式
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
int main()
{
// 1 lambda表达式
auto memberFunc1 = std::bind([](int a, int b) { std::cout << "lambda函数被调用,a =" << a << ",b=" << b << std::endl; }, std::placeholders::_1, std::placeholders::_2);
memberFunc1(1, 2);
getchar();
return 0;
}
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++11 – std::bind简要介绍以及可绑定函数的几种形式总结
原文链接:https://www.stubbornhuang.com/917/
发布于:2020年09月24日 16:18:59
修改于:2023年06月26日 22:14:55
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
52