c++函数式编程 笔记
2023-09-14 09:08:24 时间
函数可以看作是一个普通变量。可被存储在集合或结构中,作为参数传递给其他函数,或作为函数的返回值。
高阶函数:能够接收函数作为参数或者返回函数作为结果的函数。
- filter:过滤后集合类型不变
一个类型:T
包含T类型的集合:Collection<T> or C<T>
filter函数原型就可以写作:
(Collection<T>, (T->bool)) **->** Collection<T>
()这个括号代表函数;
"->"符号后面是返回值类型`
T->bool这个指的是一个函数,接收一个T类型参数,返回bool值。就是lamba表达式。
(Collection
- map/transform: 返回值可以是其他类型(输入是IN类型集合,输出是OUT类型的集合,所以名字叫变形呢
(Collection<In>, (In->Out)) -> Collection<Out>
累加器 std::accumulate/ folding/ reducing: 对递归结构(vector,list,tree...)遍历,并逐步构建自己需要的结果。
(std::reduce可实现并行效果)
折叠接收集合包含T类型条目,R类型的初始值和一个函数f:(R,T)->R
过滤函数区别
filer 是对T返回bool;
transform 对T返回另外一种类型 "T1";
accumulate 对 上次结果R和T,用f函数运算f(R,T), 返回 结果R类型的值。R可以是个集合,实现搜集。
循环与递归
纯FP不存在循环,用递归实现。思想是,对于一个集合,递归地处理它的头(第一个元素)和尾(其他所有元素),这又可以看作集合。
分别对头和尾做处理。尾就又递归调用自身处理。
其实 accumulate 就是遍历元素的很好方法。将返回可以全部放到新的集合中。
std::accumulate 实现原理 与 demo
实现:
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, class 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;
}
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';
注意 std::next ,郁闷死了,我说怎么取第二个值了。
相关文章
- C++系列笔记(五)
- C++系列笔记(六)
- C++系列笔记(十一)
- C++系列笔记(十二)
- EasyC++56,类的定义
- EasyC++73,成员初始化列表
- c++之编程模块笔记
- c++之复合类型笔记(二)
- C++模版笔记(1)
- c++的链表-链表入门(C++)
- C/C++ 操作数组与指针笔记
- C/C++中void用法总结
- C++11新特性学习笔记
- C++函数模板与类模板
- C++ 中文周刊 第108期
- devc++控制台输出中文乱码解决方案
- 树和二叉树的存储结构的实现(C/C++实现)详解编程语言
- C++箴言:避免构造或析构函数中调用虚函数详解编程语言
- C++ array迭代器及用法
- C++ deque添加和删除元素方法详解
- C++ string类库简介
- C++Primer笔记之关联容器的使用详解
- C++Primer笔记之顺序容器的使用详解
- C++中引用(&)的用法与应用实例分析
- c++验证哥德巴赫猜想