概述
文章目录
- 1. 可调用对象
- 实例
- 2.可调用对象包装器 std::function
- 实例
- 1.包装普通函数
- 2.包装模板函数
- 3.包装lambda表达式
- 4. 包装函数对象
- 非模板类型
- 模板类型:
- 5.包装类静态成员函数
- 非模板类型
- 模板类型:
- 6. 包装类对象成员函数
- 非模板类型:
- 模板类型:
- 7. 拷贝、移动
1. 可调用对象
c++中,可调用对象有如下几种定义:
- 函数指针
- 一个具有operator()成员函数的类对象
- 一个可被转换为函数指针的类对象
- 一个类成员(函数)指针
实例
- 函数指针
void func(void)
{
//....
}
- 一个具有operator()成员函数的类
struct Foo
{
void operator()(void)
{
//...
}
}
- 一个可被转换为函数指针的类对象
struct Bar
{
using fr_t = void(*)(void);
static void func(void)
{
//...
}
operator fr_t(void )
{
return func;
}
};
- 一个类成员(函数)指针
struct A
{
int a_;
void mem_func(void )
{
//...
}
}
调用代码
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.包装普通函数
#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.包装模板函数
#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表达式
#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. 包装函数对象
非模板类型
#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;
}
模板类型:
#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.包装类静态成员函数
非模板类型
#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;
}
模板类型:
#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. 包装类对象成员函数
非模板类型:
#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;
}
模板类型:
#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. 拷贝、移动
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++ std::function1. 可调用对象2.可调用对象包装器 std::function所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复