c++函数式编程 笔记

函数可以看作是一个普通变量。可被存储在集合或结构中,作为参数传递给其他函数,或作为函数的返回值。
高阶函数:能够 接收函数作为参数或者 返回函数作为结果的函数。

  • filter:过滤后集合类型不变
    一个类型:T
    包含T类型的集合: Collection<t> or C<t></t></t>
    filter函数原型就可以写作:

(Collection<t>, (T->bool)) **->** Collection<t> </t></t>
()这个括号代表函数;
“->”符号后面是返回值类型`
T->bool这个指的是一个函数,接收一个T类型参数,返回bool值。就是lamba表达式。
(Collection, (T->bool)) 这个就是接收两个参数,一个集合T,另一个就是上面说那个函数。后面->Collection 指返回还是集合T。

  • map/transform: 返回值可以是其他类型(输入是IN类型集合,输出是OUT类型的集合,所以名字叫变形呢
    (Collection<in>, (In->Out)) -> Collection<out> </out></in>

累加器 std::accumulate/ folding/ reducing: 对递归结构(vector,list,tree…)遍历,并逐步构建自己需要的结果。
(std::reduce可实现并行效果)
&#x6298;&#x53E0;&#x63A5;&#x6536;&#x96C6;&#x5408;&#x5305;&#x542B;T&#x7C7B;&#x578B;&#x6761;&#x76EE;&#xFF0C;R&#x7C7B;&#x578B;&#x7684;&#x521D;&#x59CB;&#x503C;&#x548C;&#x4E00;&#x4E2A;&#x51FD;&#x6570;f&#xFF1A;(R,T)->R

过滤函数区别

filer 是对T返回bool;
transform 对T返回另外一种类型 “T1″;
accumulate 对 上次结果R和T,用f函数运算f(R,T), 返回 结果R类型的值。R可以是个集合,实现搜集。

纯FP不存在循环,用递归实现。思想是,对于一个集合,递归地处理它的头(第一个元素)和尾(其他所有元素),这又可以看作集合。
分别对头和尾做处理。尾就又递归调用自身处理。
其实 accumulate 就是遍历元素的很好方法。将返回可以全部放到新的集合中。

实现:

template<class inputit, class t>
constexpr // since C++20
T accumulate(InputIt first, InputIt last, T init)
{
    for (; first != last; ++first) {
        init = std::move(init) + *first; // std::move since C++20
    }
    return init;
}

template<class inputit, class t, binaryoperation>
constexpr // since C++20
T accumulate(InputIt first, InputIt last, T init,
             BinaryOperation op)
{
    for (; first != last; ++first) {
        init = op(std::move(init), *first); // std::move since C++20
    }
    return init;
}
</class></class>

demo:

    const std::vector<int> ds = { 1, 2, 3 };
    int n = std::accumulate(ds.begin(), ds.end(),
        0,
        [](int a, int d) {
            cout << a << " " << d << endl;
            return a * 10 + d;

        });
    std::cout << n << std::endl;

    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    int sum = std::accumulate(v.begin(), v.end(), 0);

    int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());

    auto dash_fold = [](std::string a, int b) {
                         return std::move(a) + '-' + std::to_string(b);
                     };

    std::string s = std::accumulate(std::next(v.begin()), v.end(),
                                    std::to_string(v[0]), // start with first element
                                    dash_fold);

    // Right fold using reverse iterators
    std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
                                     std::to_string(v.back()), // start with last element
                                     dash_fold);

    std::cout << "sum: " << sum << '\n'
              << "product: " << product << '\n'
              << "dash-separated string: " << s << '\n'
              << "dash-separated string (right-folded): " << rs << '\n';
</int></int></int>

注意 std::next ,郁闷死了,我说怎么取第二个值了。

Original: https://www.cnblogs.com/bigben0123/p/16221533.html
Author: Bigben
Title: c++函数式编程 笔记

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535470/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • c++ 条件变量

    http://blog.csdn.net/hemmanhui/article/details/4417433 互斥锁:用来上锁。 条件变量:用来等待,当条件变量用来自动阻塞一个线程…

    C++ 2023年5月29日
    043
  • C++的sort函数

    参考: https://baike.baidu.com/item/sort%E5%87%BD%E6%95%B0/11042699?fr=aladdin https://blog.c…

    C++ 2023年5月29日
    067
  • Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题

    最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了…

    C++ 2023年5月29日
    030
  • c++11 thread

    官方例子 // thread example #include // std::cout #include // std::thread #include using namesp…

    C++ 2023年5月29日
    070
  • C++ *和&

    概述 在c++中,当申明变量int *p 的时,表示p是一个储存地址的变量;比如int _p=0,表示p指向地址为00000000的地址单元。当申明指针p之后,再用_p表示p指向的…

    C++ 2023年5月29日
    057
  • 聊聊 C++ 中几类特殊成员函数

    一:背景 在 C# 中要说 &#x7C7B;默认给我们定义的特殊成员函数,莫过于 &#x6784;&#x9020;&#x51FD;&#x65…

    C++ 2023年5月29日
    056
  • C++11 并发指南三(Lock 详解)

    C++11 标准为我们提供了两种基本的锁类型,分别如下: std::lock_guard,与 Mutex RAII 相关,方便线程对互斥量上锁。 std::unique_lock,…

    C++ 2023年5月29日
    070
  • 解决JAVA调用C++ DLL文件Unable to load library的问题

    JAVA项目开发中,有时候会遇到调用C++编写的动态链接库的场景(比如调用第三方的动态链接库、软件中关键部分用C++编码提供给外部调用)。我们知道JAVA调用动态链接库(C/C++…

    C++ 2023年5月29日
    091
  • UNITY 手游(安卓)如何使用C/C++代码

    解决方案:将C/C++代码编译成so供C#代码调用。 SO生成工具:android studio,简称AS 一,so 生成方法: 1,菜单:File->New->New…

    C++ 2023年5月29日
    076
  • vscode配置c++

    在.vscode里创建三个文件 c_cpp_properties.json, launch.json, settings.json, tasks.json c_cpp_proper…

    C++ 2023年5月29日
    072
  • std::get<C++11多线程库~线程间共享数据>(10):使用互斥量保护共享数据(2)

    1 #ifndef USE_CODE_PROTECTED_DATA_H 2 #define USE_CODE_PROTECTED_DATA_H 3 4 /* 5 * &#x8BDD…

    C++ 2023年5月29日
    046
  • c++ 智能指针的向下转换 向下塑型 cast

    class A { public: void test() { std::cout << "test" << std::endl; } …

    C++ 2023年5月29日
    068
  • 玩转cocos2d-x lua-binding, 实现c++与lua混合编程

    引言 城市精灵GO(http://csjl.teamtop3.com/)是一款基于cocos2d-x开发的LBS社交游戏, 通过真实地图的探索, 发现和抓捕隐匿于身边的野生精灵, …

    C++ 2023年5月29日
    052
  • [C++] 引用

    引用的特点 通常意义上的引用是”左值引用”,(相对于右值引用,即 rvalue reference)。 引用是语法糖,变量别名。声明一个引用,不是新定义了一…

    C++ 2023年5月29日
    047
  • C+++string类如何判断字符串为空

    string类是C++STL类之一,有很丰富的接口。 string类为空,实际也就是元素为0个。 可以按照如下方式判断: 1、string类有自己的成员函数empty, 可以用来判…

    C++ 2023年5月29日
    064
  • C++11中的右值引用及move语义编程

    C++0x中加入了右值引用,和move函数。右值引用出现之前我们只能用const引用来关联临时对象(右值)(造孽的VS可以用非const引用关联临时对象,请忽略VS),所以我们不能…

    C++ 2023年5月29日
    061
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球