C++进阶:模板与函数式编程

C++进阶:模板与函数式编程

1. 前置知识: 函数指针——将函数作为参数

这一部分随便看看,看不懂无伤大雅, 了解有这个东西就行, 不用深究

void fun(int n) {
    ...
}

void Func(void (*p)(int)) {
	...
}
// 这里这个参数p的类型 void (*)(int) 就是返回值为void参数为int的函数的指针
// 括号不能丢 丢了就是返回值为void*的函数

int main() {
    Func(&fun);
}

当然不一定非要传一个函数指针进去, 传函数也可

下面是两种的对比

#include <iostream>
#include <vector>


void num(int n) {
    std::cout << n << std::endl;
}


// 传函数
void func1(void p(int)) {	
    p(1);
    p(2);
}


// 传函数指针
void func2(void (*p)(int)) {
    p(1);
    p(2);
    p(3);
}

int main() {
    func1(num);
    func2(&num);
    return 0;
}

如果非要深究, 为什么直接传函数也可以, 其实这是c++的特色, 写成传函数和传函数指针是一个道理, 都是函数指针, 这俩就是完全等价的

2. 没有模板的函数式编程: 不好用

#include <iostream>
#include <vector>

void num(int n) {
    std::cout << n << std::endl;
}

void Func(void fun(int), std::vector<int> arr) {
    for(auto i : arr) {
        fun(i);
    }
}

int main() {
    Func(num, std::vector<int>{1, 2, 3});
    return 0;
}

就很别扭, 并且函数返回类型, 参数列表都要一致,除了一些特殊场景其它场景都不好用

3. 模板 + 函数做参数:有奇效!真正的函数式编程

上面那种的问题很明显:

我们把函数作为参数传递, 却限制了函数的返回值, 函数的参数列表, 导致通用性很差

有没有办法能不限制函数的类型, 我们只传这个函数进去, 执行他就好

很遗憾答案是不能

虽然做不到不限制函数的类型, 但是我们可以做到在编译时传入函数的时候自动推导他的类型

简单来说就是使用模板

void int_fun(int n) {
    std::cout << "int:" << n << std::endl;
}

void float_fun(float n) {
    std::cout << "float:" << n << std::endl;
}

template<class Func>
void do_twice(Func fun) {
    fun(1);
    fun(2);
}

int main() {
    do_twice(int_fun);
    do_twice(float_fun);
    return 0;
}

4. lambda表达式(匿名函数): 函数式编程大杀器(C++11引入)

示例

std::vector<int> v{1, 2, 3};

template<class Func>
int for_all(Func fun) {
   	int a{0};
    for(auto i : v) {
        a += fun(i);
    }
}

int main() {
    // 第一种
    auto myfunc = [] (int n) {
        std::cout << n << std::endl;
    };
    for_all(myfunc);
    
    // 第二种
    for_all([] (int n) -> bool{
        std::cout << "hello!" << std::endl;
        return n > 0;
    })
}


如何定义一个匿名函数

不指定返回类型

[](int a, int b){return a + b}
  • [] //捕获列表为空。在函数内无法使用外部变量。
  • [a] //捕获列表为按值传递形式。在函数内仅能使用传递的变量值,无法改变变量。值在匿名函数生成时便已经确定,后续修改不会影响函数内的变量值。
  • [&a] //按引用传递。可改变变量。

指定返回类型

[](double a, double b)->int{return a + b;};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值