C++包装器function笔记

这篇博客探讨了如何通过std::function解决模板函数因不同参数导致的多次实例化问题。通过创建function对象,可以确保调用具有相同调用特征标的函数、函数指针和lambda表达式时,模板只实例化一次,提高了代码效率。
摘要由CSDN通过智能技术生成

功能:

包装器function能够提供统一的方式处理各种类似于函数的形式。

解决的问题:

解决模板低效性问题,例如:

template <typename T, typename F>
T use_f(T v, F f) 
{
    static int count = 0;
    count++;
    std::cout << " use_f count = " << count
              << ", &count = " << &count << std::endl;
    return f(v);
}

模板use_f使用参数f表示调用类型:return f(v);

如果使用不同的参数调用use_f,并且不论是函数对象、函数指针、Lamda表达式,所有可调用参数的调用特征标都相同:double(double),即输入double类型,返回double类型,在这种情况下,发现模板并不会因为F类型相同只实例化模板一次,根据&count可以看出,输出不同的地址,这表明实例化了多次;

例如:

double dub(double x) 
{
    return 2.0 * x;
}

class Fp
{
private:
    double z_;
public:
    Fp(double z = 1.0) : z_(z) {}
    double operator()(double p}
    {
        return z_ * p;
    }
};


int main() {
    double y = 1.21;
    cout << use_f(y, dub) << endl;
    cout << use_f(y, Fp(0.5) << endl;
    cout << use_f(y, [](double u) {return u * u;}) << endl;
    return 0;
}

三者&count值不同,表明模板实例化了三次。

修复问题

模板function是在头文件functional中声明的,它从调用特征标的角度定义了一个对象,可用于包装调用特征标相同的函数指针、函数对象、lambda表达式。

方法一:

例如:创建一个名为foo的function对象,它接受一个char参数和一个int参数,并返回一个double值

std::function<double(char, int)> foo;

那么对于上述问题,可以通过创建多个function对象或者临时对象来解决:

cout << use_f(y, function<double(double)> (dub) << endl;
cout << use_f(y, function<double(double)> (Fp(0.5) << endl;
cout << use_f(y, function<double(double)> ([](double u) {return u * u;}) << endl;

输出结果表明,&count值相同,count值依次增加,因此模板use_f只实例化了一次;

方法二:

除了让use_f的第二个实参与形参f匹配之外,还可以让形参f的类型与原始实参匹配:

template <typename T, typename F>
T use_f(T v, std::function<T(T)> f) 
{
    static int count = 0;
    count++;
    std::cout << " use_f count = " << count
              << ", &count = " << &count << std::endl;
    return f(v);
}


// 函数调用如下

...
cout << use_f<double>(y, dub) << endl;
cout << use_f<double>(y, Fp(0.5)) << endl;
cout << use_f<double>(y, [] (double u) {return u * u;}) << endl;

参数dub、Fp(0.5)等本身类型并不是function<double(double)>,因此在use_f后面使用<double>来指出所需的具体化,这样,T被置为double,而std::function<T(T)>变成了std::function<double(dobule)>。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值