C++11 – std::function简要介绍以及可包装函数的几种形式总结
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++11 – std::function简要介绍以及可包装函数的几种形式总结
原文链接:https://www.stubbornhuang.com/916/
发布于:2020年09月24日 16:07:25
修改于:2021年07月15日 21:25:54

1 std::function
函数模板形式:
template <class T>函数;//未定义
模板<class Ret,class ... Args> class function <Ret(Args ...)>;
1.1 函数模板说明
std::function是一个函数包装器模板,该函数包装器模板可以包装任意可以调用的元素,其包装器的类型只依赖于其调用特征,而不依赖于可调用元素自身的类型。
std::function可包装下列可调用元素类型:
- 函数
- 函数指针
- 类成员函数
- 任意类型的函数可调用对象(比如重载了operator()操作符并且拥有函数闭包的函数体对象)
- ...
std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素。
当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常。
1.2 模板参数说明
- T : 通用类型,但实际通用类型模板并没有被定义,只有当T的类型为形如Ret(Args...)的函数类型才能工作;
- Ret :调用函数返回值的类型;
- Args:函数参数类型,对于指向成员函数的指针,第一个参数应该是指向该成员函数的引用或者对象。
2 std::function可包装的几种函数形式总结
2.1 包装普通函数和静态函数
2.1.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
int Add(int a, int b)
{
std::cout << "普通函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
static int StaticAdd(int a, int b)
{
std::cout << "静态函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
int main()
{
// 1 普通函数
std::function<int(int, int)> addFunc1 = Add;
addFunc1(1, 2);
// 2 普通函数指针
std::function<int(int, int)> addFunc2 = &Add;
addFunc2(3, 4);
// 3 静态函数
std::function<int(int, int)> staticAddFunc1 = StaticAdd;
staticAddFunc1(5, 6);
// 4 静态函数指针
std::function<int(int, int)> staticAddFunc2 = &StaticAdd;
staticAddFunc2(7, 8);
getchar();
return 0;
}
2.1.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template <class T>
T Add(T a, T b)
{
std::cout << "普通模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
template <class T>
static T StaticAdd(T a, T b)
{
std::cout << "静态模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
int main()
{
// 1 普通函数
std::function<int(int, int)> addFunc1 = Add<int>;
addFunc1(1, 2);
// 2 普通函数指针
std::function<int(int, int)> addFunc2 = &Add<int>;
addFunc2(3, 4);
// 3 静态函数
std::function<int(int, int)> staticAddFunc1 = StaticAdd<int>;
staticAddFunc1(5, 6);
// 4 静态函数指针
std::function<int(int, int)> staticAddFunc2 = &StaticAdd<int>;
staticAddFunc2(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:
int A_Add_Public(int a, int b)
{
std::cout << "类公有成员函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
static int A_Add_Static(int a, int b)
{
std::cout << "类静态函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类公有成员函数
A m_a;
std::function<int(int, int)> addFunc1 = std::bind(&A::A_Add_Public, &m_a, std::placeholders::_1, std::placeholders::_2);
addFunc1(1, 2);
// 2 类静态函数
std::function<int(int, int)> addFunc2 = &A::A_Add_Static;
addFunc2(1, 2);
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>
T A_Add_Public(T a, T b)
{
std::cout << "类公有模板成员函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
template <class T>
static T A_Add_Static(T a, T b)
{
std::cout << "类静态模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类公有成员函数
A m_a;
std::function<int(int, int)> addFunc1 = std::bind(&A::A_Add_Public<int>, &m_a, std::placeholders::_1, std::placeholders::_2);
addFunc1(1, 2);
// 2 类静态函数
std::function<int(int, int)> addFunc2 = &A::A_Add_Static<int>;
addFunc2(1, 2);
getchar();
return 0;
}
2.3 包装Lambda表达式
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
int main()
{
// 1 lambda表达式
std::function<int(int, int)> addFunc1 = [](int a, int b) ->int {
std::cout << "lambda表达式被调用,结果为:" << a + b << std::endl;
return a + b;
};
addFunc1(1, 2);
getchar();
return 0;
}
2.4 包装类重载操作符()函数
2.4.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
int operator()(int a, int b)
{
std::cout << "类重载操作符()函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类重载操作符()函数
std::function<int(int, int)> addFunc1 = A();
addFunc1(1, 2);
getchar();
return 0;
}
2.4.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template <class T>
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
T operator()(T a, T b)
{
std::cout << "类重载操作符()模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类重载操作符()函数
std::function<int(int, int)> addFunc1 = A<int>();
addFunc1(1, 2);
getchar();
return 0;
}
2.5 包装类共有成员变量
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
int Add()
{
return m_Value;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类共有成员变量
std::function<int(A&)> A_Value = &A::m_Value;
A m_a;
std::cout << "m_a对象的成员m_Value的值为:" << A_Value(m_a) << std::endl;
getchar();
return 0;
}
当前分类随机文章推荐
- C++ - std::string输出双引号到字符串 阅读2890次,点赞0次
- C++ - 字节数组byte[]或者unsigned char[]与int的相互转换 阅读6553次,点赞1次
- C++ - 使用模板和智能指针构建一个双向链表工具类 阅读808次,点赞0次
- C++ - 一文搞懂std::future、std::promise、std::packaged_task、std::async的使用和相互区别 阅读163次,点赞0次
- C++STL容器 - std::map删除指定元素 阅读1670次,点赞0次
- C++11/std::atomic - 原子变量(不加锁实现线程互斥) 阅读6108次,点赞2次
- C++ - 格式化json字符串,方便展示json字符串的层次结构 阅读2554次,点赞0次
- C++ - sleep睡眠函数总结 阅读907次,点赞0次
- C++ - 获取std::vector中的最小值、最大值以及对应的索引 阅读15次,点赞0次
- C++11 - 构建一个符合实际应用要求的线程池 阅读1038次,点赞0次
全站随机文章推荐
- 资源分享 - Artificial Intelligence - A Modern Approach , Fourth Edition 英文高清PDF下载 阅读4051次,点赞0次
- 如何选择一块合适的用于深度学习的GPU/显卡 阅读1382次,点赞0次
- opencv-python - 读取视频,不改变视频分辨率修改视频帧率 阅读4679次,点赞2次
- Python - 使用websockets库构建websocket服务器 阅读1526次,点赞0次
- 资源分享 - Efficient Illumination Algorithms for Global Illumination In Interactive and Real-Time Rendering英文PDF下载 阅读2476次,点赞0次
- ThreeJS - FBXLoader: TGA loader not found, creating placeholder texture for ... 阅读492次,点赞0次
- 深度学习 - CTC解码算法详解 阅读655次,点赞0次
- 资源分享 - Direct3D Rendering Cookbook 英文高清PDF下载 阅读1042次,点赞0次
- C++ - GBK编码下的全角字符转半角字符 阅读1481次,点赞0次
- UnrealEngine4 - Can not find such file SceneRenderTargets.h,在UE4 C++层中正确的使用FSceneRenderTargets类 阅读2669次,点赞0次
评论
167