函数指针,function,bind, lambda

函数指针,

sd::function<type0 (type1, type2...)> functionObject, 

std::bind()


1. 函数指针是类型不安全的,为什么?

#include<stdio.h>
int max(int x,int y){return (x>y? x:y);}
int main()
{
    int (*ptr)(int, int);
    int a, b, c;
    ptr = max;
    scanf("%d%d", &a, &b);
    c = (*ptr)(a,b);
    printf("a=%d, b=%d, max=%d", a, b, c);
    return 0;
}


C语言的函数指针就是一个地址变量,在赋值和调用的时候没有任何类型检查。

任何一种函数指针都可以转型为其他类型的函数指针, 当转型回来时, 与原函数指针相同。

必须由程序员自己记住究竟是什么类型。

转型错了,cast完蛋。

这就是类型不安全的。


函数指针无法提前在编译器给出错误提示。这个是于


2. std::function

将一个函数放入一个函数对象中

#include < functional>
 
std::function< size_t(const char*)> print_func;
 
/// normal function -> std::function object
size_t CPrint(const char*) { ... }
print_func = CPrint;
print_func("hello world"):
// 以下效果相同
//====================
/// functor -> std::function object
class CxxPrint
{
public:
    size_t operator()(const char*) { ... }
};
CxxPrint p;
print_func = p;
print_func("hello world");

function<float (int x, int y)> f;        // 构造一个函数对象,它能表示的是一个返回值为float,两个参数为int,int的函数

function的参数类型会进行类型检查,保证类型安全。


3. std::bind

将变量或值绑定到函数参数中,对于预先绑定的参数,是pass-by-value的

#include < functional>
 
int Func(int x, int y);
auto bf1 = std::bind(Func, 10, std::placeholders::_1);
bf1(20); ///< same as Func(10, 20)

std::bind绑定后,可以赋值给auto变量,也可以给function对象。
auto自动类型定义。

A a;
auto bf2 = std::bind(&A::Func, a, std::placeholders::_1, std::placeholders::_2);
bf2(10, 20); ///< same as a.Func(10, 20)
 
std::function< int(int)> bf3 = std::bind(&A::Func, a, std::placeholders::_1, 100);
bf3(10); ///< same as a.Func(10, 100)

1. 对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的

2. bind的返回值是可调用实体,可以直接赋给std::function对象

3. bind能保证类型安全,但对于绑定变量的内容,需要程序员保证有效性


4. lambda

用于实现一个匿名函数,最大的用途就是callback回调函数。

实例1:

vector< int> vec;
/// 1. simple lambda
auto it = std::find_if(vec.begin(), vec.end(), [](int i) { return i > 50; });

其效果等同于一个函数对象。


可以有返回值,如果capture上下文环境,可以使用外部的局部变量,或类的成员变量

/// 2. lambda expr: capture of local variable
{
    int min_val = 10;
    int max_val = 1000;
 
    auto it = std::find_if(vec.begin(), vec.end(), [=](int i) {
        return i > min_val && i < max_val; 
        });
}

[=], [&], 

=表示capture的变量pass-by-value, 第二个小拿出中&表示capture的变量pass-by-reference


在使用function时,参数多的时候,bind要传入很多的std::placeholders,而且看着没有lambda表达式直观,所以通常建议优先考虑使用lambda表达式


参考学习:

http://www.wuzesheng.com/?p=2032

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
callback函数是一种常见的编程模式,用于在某个事件发生时执行特定的操作。在C++中,通常使用函数指针或者函数对象作为callback函数的参数,以便在需要时调用该函数。 lambda表达式是C++11引入的一种匿名函数的语法,它可以用来创建临时的函数对象。lambda表达式可以捕获外部变量,并且可以作为callback函数的替代品。 使用lambda表达式取代std::bind可以简化代码,并且提供更好的可读性和灵活性。std::bind是一个函数模板,用于将函数和参数绑定在一起,生成一个新的可调用对象。而lambda表达式可以直接在需要的地方定义和使用,不需要额外的绑定操作。 下面是一个示例,展示了如何使用lambda表达式取代std::bind来实现callback函数: ```cpp #include <iostream> #include <functional> // 定义callback函数类型 using Callback = std::function<void(int)>; // 使用lambda表达式作为callback函数 void doSomething(Callback callback) { int result = 42; callback(result); } int main() { // 使用lambda表达式作为callback函数的实现 doSomething([](int result) { std::cout << "Callback function called with result: " << result << std::endl; }); return 0; } ``` 在上面的示例中,我们定义了一个类型别名Callback来表示callback函数的类型。然后,在doSomething函数中,我们使用lambda表达式作为callback函数的实现。lambda表达式接受一个int类型的参数,并在函数体中输出该参数的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值