我是靠谱客的博主 清秀狗,这篇文章主要介绍c++ std::function1. 可调用对象2.可调用对象包装器 std::function,现在分享给大家,希望可以做个参考。

文章目录

  • 1. 可调用对象
    • 实例
  • 2.可调用对象包装器 std::function
    • 实例
      • 1.包装普通函数
      • 2.包装模板函数
      • 3.包装lambda表达式
      • 4. 包装函数对象
          • 非模板类型
          • 模板类型:
      • 5.包装类静态成员函数
          • 非模板类型
          • 模板类型:
      • 6. 包装类对象成员函数
          • 非模板类型:
          • 模板类型:
      • 7. 拷贝、移动

1. 可调用对象

c++中,可调用对象有如下几种定义:

  1. 函数指针
  2. 一个具有operator()成员函数的类对象
  3. 一个可被转换为函数指针的类对象
  4. 一个类成员(函数)指针

实例

  1. 函数指针
复制代码
1
2
3
4
5
void func(void) { //.... }
  1. 一个具有operator()成员函数的类
复制代码
1
2
3
4
5
6
7
8
struct Foo { void operator()(void) { //... } }
  1. 一个可被转换为函数指针的类对象
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Bar { using fr_t = void(*)(void); static void func(void) { //... } operator fr_t(void ) { return func; } };
  1. 一个类成员(函数)指针
复制代码
1
2
3
4
5
6
7
8
9
struct A { int a_; void mem_func(void ) { //... } }

调用代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(void) { void (* func_ptr)(void) = &func; //1. 函数指针 func_ptr(); Foo foo; foo(); //2. 一个具有operator()成员函数的类 仿函数 Bar bar; bar(); //一个可被转换为函数指针的类对象 void (A::*mem_func_ptr)(void) = &A::mem_func; //4 类成员函数指针 int A::*mem_obj_ptr = &A::a_; //类成员指针 A aa; (aa.*mem_func_ptr)(); aa.*mem_obj_ptr = 123; retrun 0; }

从上述看出,除了类的成员指针调用 aa.*mem_obj_ptr = 123;,其他的调用均可以像一个函数一样做调用操作,即 func_ptr(); foo(); bar(); (aa.*mem_func_ptr)();

所以可调用对象五花八门,当我们试图用统一的方式来保存,或传递一个可调用对象时,会十分繁琐。
由此引入了 std::funcution 和 std::bind,统一了可调用对象的各种操作

2.可调用对象包装器 std::function

std::function是一个函数包装器,该函数包装器模板能包装任何类型的可调用实体,如普通函数,函数对象,lamda表达式等。包装器可拷贝,移动等,并且包装器类型仅仅依赖于调用特征,而不依赖于可调用元素自身的类型。std::function是C++11的新特性,包含在头文件中。

一个std::function类型对象实例可以包装下列这几种可调用实体:函数、函数指针、成员函数、静态函数、lamda表达式和函数对象。std::function对象实例可被拷贝和移动,并且可以使用指定的调用特征来直接调用目标元素。当std::function对象实例未包含任何实际可调用实体时,调用该std::function对象实例将抛出std::bad_function_call异常。

实例

1.包装普通函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream> #include <functional> using namespace std; int g_Minus(int i, int j) { return i - j; } int main() { function<int(int, int)> f = g_Minus; cout << f(1, 2) << endl; // -1 return 1; }

2.包装模板函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream> #include <functional> using namespace std; template <class T> T g_Minus(T i, T j) { return i - j; } int main() { function<int(int, int)> f = g_Minus<int>; cout << f(1, 2) << endl; // -1 return 1; }

3.包装lambda表达式

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream> #include <functional> using namespace std; auto g_Minus = [](int i, int j){ return i - j; }; int main() { function<int(int, int)> f = g_Minus; cout << f(1, 2) << endl; // -1 return 1; }

4. 包装函数对象

非模板类型
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream> #include <functional> using namespace std; struct Minus { int operator() (int i, int j) { return i - j; } }; int main() { function<int(int, int)> f = Minus(); cout << f(1, 2) << endl; // -1 return 1; }
模板类型:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream> #include <functional> using namespace std; template <class T> struct Minus { T operator() (T i, T j) { return i - j; } }; int main() { function<int(int, int)> f = Minus<int>(); cout << f(1, 2) << endl; // -1 return 1; }

5.包装类静态成员函数

非模板类型
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream> #include <functional> using namespace std; class Math { public: static int Minus(int i, int j) { return i - j; } }; int main() { function<int(int, int)> f = &Math::Minus; cout << f(1, 2) << endl; // -1 return 1; }
模板类型:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream> #include <functional> using namespace std; class Math { public: template <class T> static T Minus(T i, T j) { return i - j; } }; int main() { function<int(int, int)> f = &Math::Minus<int>; cout << f(1, 2) << endl; // -1 return 1; }

6. 包装类对象成员函数

非模板类型:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream> #include <functional> using namespace std; class Math { public: int Minus(int i, int j) { return i - j; } }; int main() { Math m; function<int(int, int)> f = bind(&Math::Minus, &m, placeholders::_1, placeholders::_2); cout << f(1, 2) << endl; // -1 return 1; }
模板类型:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream> #include <functional> using namespace std; class Math { public: template <class T> T Minus(T i, T j) { return i - j; } }; int main() { Math m; function<int(int, int)> f = bind(&Math::Minus<int>, &m, placeholders::_1, placeholders::_2); cout << f(1, 2) << endl; // -1 return 1; }

7. 拷贝、移动

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int callback(int p) { //... return p; } int main(int argc, char *argv[]){ std::cout << "Hello world" << std::endl; std::function<int(int)> callback2 = callback; //拷贝赋值运算符 std::cout << callback2(7) << std::endl; std::function<int(int)>&& callback3 = std::move(callback); //移动赋值运算符 std::cout << callback3(7) << std::endl; std::cout << callback(7) << std::endl; std::function<int(int)> callback4(callback); //拷贝 std::cout << callback4(7) << std::endl; return 0; }

最后

以上就是清秀狗最近收集整理的关于c++ std::function1. 可调用对象2.可调用对象包装器 std::function的全部内容,更多相关c++内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部