std::function 是一种通用的多态函数包装器 。std::function 的实例可以存储、复制和调用任何可调用的目标——函数、lambda表达式、绑定表达式或其他函数对象,以及指向成员函数的指针和指向数据成员的指针(统称为“可调用对象”)。
基类:Base.h
#pragma once
// 基类
class CBase
{
public:
CBase(){}
~CBase() {}
virtual void Run() {}
};
派生类: Function.h
#pragma once
#include "Base.h"
#include <functional>
#include <string>
#include <vector>
#include <atomic>
#include <iostream>
#include<numeric>
#include <mutex>
#include <condition_variable>
#include <stdarg.h> //标准参数:模拟可变参数必需的头文件
using namespace std;
//std::function 函数对象(也称“函数符”)是重载了“()”操作符的普通类对象
//对象是对C++中现有的可调用实体的一种类型安全的包裹--像函数指针这类可调用实体,是类型不安全的
/******************std::function注意事项******************
(1)关于可调用实体转换为std::function对象需要遵守以下两条原则:
a.转换后的std::function对象的参数能转换为可调用实体的参数
b.可高用实体的返回值能转换为std::function对象的(这里注意,所有的可调用实体的返回值都与返回void的std::function对象的返回值兼容)。
(2)std::function对象可以refer to满足(1)中条件的任意可调用实体
(3)std::function object最大的用处就是在实现函数回调,使用者需要注意,它不能被用来检查相等或者不相等
*/
//普通函数
//int Add(int x, int y){ return x + y; }
//std::function<int(int, int)> fun = Add;
//int nRet = fun(2, 3);
class CFunction : public CBase
{
public:
CFunction() {}
virtual ~CFunction() {}
virtual void Run();
// 重载()运算符 [11/2/2018 shike]
void operator()(std::string strName, int nAge)
{
printf("Name:%s, Age:%d\n", strName.c_str(), nAge);
}
int Func(int x, int y);
private:
std::function<void(std::string, int)> m_fun;
};
// std::bind
// 把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调用实体,这种机制在回调函数也有用
class CBind : public CBase
{
public:
CBind() {}
virtual ~CBind() {}
virtual void Run();
int Func(int x, int y);
private:
int m_Age = 0;
};
Function.cpp
#include "stdafx.h"
#include "Function.h"
#include <algorithm>
#include <map>
#include <iostream>
#include <thread>
void CFunction::Run()
{
printf("========std::function==========\n");
m_fun = CFunction();
m_fun("张三", 25);
// 对象成员函数绑定,注意收个函数为类对象引用或指针, 或者本类指针
std::function<int(CBind *, int, int)> fun = &CBind::Func;
fun(&CBind(), 10, 100);
}
int CFunction::Func(int x, int y)
{
printf("[std::function] X = %d, Y = %d\n", x, y);
return 0;
}
void CBind::Run()
{
printf("========std::bind==========\n");
// 绑定成员函数,保存为仿函数
std::function<int(int, int)> fun = std::bind(&CBind::Func, this, std::placeholders::_1, std::placeholders::_2);
fun(20, 30);
auto fun1 = std::bind(&CFunction::Func, &CFunction(), std::placeholders::_1, 10);
fun1(10);
auto fVal = std::bind(&CBind::m_Age, this); // 也可绑定成员变量, 对成员变量进行赋值
fVal() = 100;
printf("Age = %d\n", m_Age);
// 注意:无法使用std::bind()绑定一个重载函数
}
int CBind::Func(int x, int y)
{
printf("[std::bind] X = %d, Y = %d\n", x, y);
return 0;
}
调用:main.cpp
// C++11Demo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "XMacro.h"
#include <time.h>
#include <thread>
#include "Function.h"
#include "Thread.h"
#include <iomanip>
#include "Template.h"
#include <iostream>
#include "Mutex.hpp"
#pragma warning( disable : 4996 )
/*
1. X宏
2. std::function
3. std::bind
4. std::for_each
5. Lambda表达式
6. std::atomic
7. auto
8. std::thread
9. 模板
*/
#define Tab printf("\n");
int main()
{
//测试std::function
std::shared_ptr<CBase> pFunction = std::make_shared<CFunction>();
pFunction->Run(); Tab;
//测试std::bind
std::shared_ptr<CBase> pBind = std::make_shared<CBind>();
pBind->Run(); Tab;
return 0;
}
运行结果: