C++11包装器

文章目录

背景

在C++98及之前的标准中,处理函数指针和回调函数时常常会遇到类型不匹配、灵活性差等问题。为了解决这些问题,C++11引入了function,它是一个通用的多态函数包装器,能够存储、复制及调用任何可调用目标(Callable target)——函数、lambda表达式、绑定表达式(bind expression)以及其他函数对象,并可以作为它们的通用类型。

function

function 是一个模板类,它可以存储、复制、以及调用任何可以调用的目标(Callable),比如函数、Lambda表达式、函数对象、以及绑定表达式等。它提供了一种通用的方式来处理这些可调用对象,使得函数式编程和回调机制在C++中变得更加容易和灵活。

作用
1.提供了一种类型安全的封装来存储和调用可调用对象。
2.增强了代码的灵活性和可重用性。
3.使得函数指针、Lambda表达式等可以统一处理。

用法

#include <iostream>  
#include <functional>  
  
// 一个普通的函数  
int add(int x, int y) {  
    return x + y;  
}  
  
int main() {  
    // 使用std::function来封装一个函数指针  
    std::function<int(int, int)> funcPtr = add;  
  
    // 使用std::function来封装一个Lambda表达式  
    std::function<int(int, int)> lambdaFunc = [](int x, int y) { return x * y; };  
  
    // 调用  
    std::cout << "Function pointer: " << funcPtr(2, 3) << std::endl;  // 输出 5  
    std::cout << "Lambda expression: " << lambdaFunc(2, 3) << std::endl; // 输出 6  
  
    return 0;  
}
template<class F, class T>
T useF(F f, T x)
{
 static int count = 0;
 cout << "count:" << ++count << endl;
 cout << "count:" << &count << endl;
 return f(x);
}
double f(double i)
{
 return i / 2;
}
struct Functor
{
 double operator()(double d)
 {
 return d / 3;
 }
};

int main()
{
 // 函数名
 cout << useF(f, 11.11) << endl;
 // 函数对象
 cout << useF(Functor(), 11.11) << endl;
 // lamber表达式
 cout << useF([](double d)->double{ return d/4; }, 11.11) << endl;
 return 0;
}

上面的代码useF函数模板实例化了三份。
我们能利用function包装器优化

#include <functional>
template<class F, class T>
T useF(F f, T x)
{
 static int count = 0;
 cout << "count:" << ++count << endl;
 cout << "count:" << &count << endl;
 return f(x);
}
double f(double i)
{
 return i / 2;
}
struct Functor
{
 double operator()(double d)
 {
 return d / 3;
 }
};
int main()
{
 // 函数名
 std::function<double(double)> func1 = f;
 cout << useF(func1, 11.11) << endl;
 // 函数对象
 std::function<double(double)> func2 = Functor();
 cout << useF(func2, 11.11) << endl;
 // lamber表达式
 std::function<double(double)> func3 = [](double d)->double{ return d /
4; };
 cout << useF(func3, 11.11) << endl;
 return 0;
}

bind

bind 是一个函数模板,用于创建一个新的可调用实体(function object),该实体将给定的可调用对象(比如函数、Lambda表达式、函数对象等)与其参数进行绑定。这允许我们预先设置函数的某些参数,然后创建一个新的函数对象,这个新的函数对象在被调用时,会自动将预先设置的参数传递给原始的可调用对象。

作用
允许我们预先绑定函数的参数。
创建具有部分参数已固定的新函数对象。
在回调机制中非常有用,尤其是当回调函数需要额外信息时。

用法

#include <iostream>  
#include <functional>  
  
// 一个接受三个参数的函数  
void print(int x, int y, int z) {  
    std::cout << "x: " << x << ", y: " << y << ", z: " << z << std::endl;  
}  
  
int main() {  
    // 使用std::bind绑定前两个参数  
    auto boundFunc = std::bind(print, std::placeholders::_1, 10, std::placeholders::_2);  
  
    // 调用时,只需要提供剩余的两个参数  
    boundFunc(20, 30); // 输出: x: 20, y: 10, z: 30  
  
    // 也可以使用Lambda表达式来达到类似的效果,但std::bind在某些情况下更加直观  
  
    return 0;  
}

在上面的例子中,std::placeholders::_1 和 std::placeholders::_2 是占位符,用于表示在调用 boundFunc 时需要提供的参数。在这个例子中,boundFunc 被创建为一个新的可调用对象,它预先绑定了 print 函数的第二个参数为 10,因此当调用 boundFunc(20, 30) 时,实际上是在调用 print(20, 10, 30)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gsfl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值