概述
1.概述
-
std::function从c++11开始引入, 主要作用就是把任意的函数调用包装到一个对象里,并且这个对象,可以保存,传递,复制,然后在合适时间地点调用。
-
std::function是动态绑定的,函数或者类可以通过它实现,不改变任何代码,只需改变构造或者执行时传入的std::function对象就改变行为,类似多态的效果。
2.用法
1.声明
std::function<int(int)> fn_half;
std::function<int(int, int)> fn_add;
在模板类型里,指定函数的形式。
std::function<int(int)> 表示返回值是int, 有一个参数,类型为int的函数。
std::function<int(int, int)> 表示返回值是int, 有两个参数,类型均为int的函数。
2.调用
int half_result = fn_half(50);
std::cout << "fn_half(50)=" << half_result << std::endl;
int add_result = fn_add(2, 3);
std::cout << "fn_add(2, 3)=" << add_result << std::endl;
直接把std::function对象当作函数来调用即可,返回值以及参数都跟函数调用时一样的形式。 fn_half(50), fn_add(2, 3)。 这里std::function对象还没初始化,我们放在后面说。
3.直接指向全局函数。
int half(int x)
{
std::cout << "Global function half" << std::endl;
return x / 2;
}
int add(int x, int y)
{
std::cout << "Global function add" << std::endl;
return (x + y);
}
int main() {
std::function<int(int)> fn_half;
std::function<int(int, int)> fn_add;
fn_half = half; // 直接指向函数
int half_result = fn_half(50);
std::cout << "fn_half(50)=" << half_result << std::endl;
fn_add = add; // 直接指向函数
int add_result = fn_add(2, 3);
std::cout << "fn_add(2, 3)=" << add_result << std::endl;
return 0;
}
结果如下:
4.指向函数指针,也就是函数地址。基本代码与上面相同,唯一就是赋值函数的时候加上了&,效果与上面做法一样。
fn_half = ½ // 指向函数地址
fn_add = &add; // 指向函数地址
int main() {
std::function<int(int)> fn_half;
std::function<int(int, int)> fn_add;
fn_half = ½ // 指向函数地址
int half_result = fn_half(50);
std::cout << "fn_half(50)=" << half_result << std::endl;
fn_add = &add; // 指向函数地址
int add_result = fn_add(2, 3);
std::cout << "fn_add(2, 3)=" << add_result << std::endl;
return 0;
}
5.指向仿函数,也就是函数对象。
一个类重载operator()函数以后, 它实例就可以像函数一样来使用,它有一个名称叫做仿函数。 std::function可以直接指向仿函数的实例。
struct HalfObj
{
int operator() (int x)
{
std::cout << "functor half" << std::endl;
return (x / 2);
}
};
struct AddObj
{
int operator()(int x, int y)
{
std::cout << "functor add" << std::endl;
return (x + y);
}
};
int main() {
std::function<int(int)> fn_half;
std::function<int(int, int)> fn_add;
fn_half = HalfObj(); // 指向仿函数->函数对象
int half_result = fn_half(50);
std::cout << "fn_half(50)=" << half_result << std::endl;
fn_add = AddObj(); // 指向仿函数->函数对象
int add_result = fn_add(2, 3);
std::cout << "fn_add(2, 3)=" << add_result << std::endl;
return 0;
}
结果如下:
6.指向匿名函数。
直接在初始化std::function的地方定义匿名函数, 无需在其他地方再定义实现功能的函数,代码更加简洁,紧凑。
int main() {
std::function<int(int)> fn_half;
std::function<int(int, int)> fn_add;
// 指向匿名函数
fn_half = [](int x) { return (x / 2); };
int half_result = fn_half(50);
std::cout << "fn_half(50)=" << half_result << std::endl;
// 指向匿名函数
fn_add = [](int x, int y) {return (x + y); };
int add_result = fn_add(2, 3);
std::cout << "fn_add(2, 3)=" << add_result << std::endl;
return 0;
}
结果如下:
7.指向类成员函数。
通过std::bind函数来绑定一个类的对象, 实现指向某个对象的, 特定形式的函数调用。
class Calculate
{
public:
int base_value;
int half(int x)
{
std::cout << "Calculate member function half" << std::endl;
return (base_value + x) / 2;
}
int add(int x, int y)
{
std::cout << "Calculate member function add" << std::endl;
return (base_value + x + y);
}
};
int main() {
std::function<int(int)> fn_half;
std::function<int(int, int)> fn_add;
Calculate cal;
cal.base_value = 10;
// 指向类成员函数
fn_half = std::bind(&Calculate::half, &cal, std::placeholders::_1);
int half_result = fn_half(50);
std::cout << "fn_half(50)=" << half_result << std::endl;
// 指向类成员函数
fn_add = std::bind(&Calculate::add, &cal, std::placeholders::_1, std::placeholders::_2);
int add_result = fn_add(2, 3);
std::cout << "fn_add(2, 3)=" << add_result << std::endl;
return 0;
}
std::bind函数第一个参数是类成员函数的指针, 第二个参数是类对象的地址, 后面根据参数的个数来传入占位符std::placeholders::_1, std::placeholders::_2,std::placeholders::_3,...
_1表示第一个参数, _2表示第二个参数。 这样无论类成员函数的返回值类型,参数类型是什么,都可以通过这种通用的方式去表达。
std::bind(&Calculate::add, &cal, std::placeholders::_1, std::placeholders::_2);
结果如下:
为了表达类成员在类成员函数中起作用,例子中Calculate特意加了base_value这个成员来表达这种效果,因此最终结果与实际的half和add不一样。
最后
以上就是冷酷盼望为你收集整理的std::function用法1.概述2.用法的全部内容,希望文章能够帮你解决std::function用法1.概述2.用法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复