往期精彩:
- Modern C++ 学习笔记——易用性改进篇
- Modern C++ 学习笔记 —— 右值、移动篇
- Modern C++ 学习笔记 —— 智能指针篇
- Modern C++ 学习笔记 —— lambda表达式篇
- Modern C++ 学习笔记 —— C++面向对象编程
- Modern C++ 学习笔记 —— C++函数式编程
Modern C++ 学习笔记——C++函数式编程
关键字:lambda表达式、函数式编程
文章目录
函数式编程
在之前的系列文章中介绍过函数对象和lambda表达式,本篇文章就来讲讲它们的主要用途——函数式编程。
什么是函数式编程?
那什么是函数编程呢?它其实来自于数学中的理念.
f(x) = 2x^2 +x+3
g(x) = 3f(x) + 5 = 6x^2 + 3x + 14
h(x) = f(x) + g(x) = 8x^2 + 4x + 17
正如上面的数学函数一样,对于函数式编程,它只关心于定义输入数据和输出数据的关系,在数学表达式中我们称其为输入与输出的一种映射(map),即用函数定义输入数据和输出数据的关系是什么样的。
这样就可以得到关于函数式编程一下特点:
- 无状态:函数不维护任何状态。函数式编程的核心精神是stateless。
- 不可变数据:输入数据不可变,动了输入数据就有危险,所以要返回新的数据集。
或许这么说有点干燥,为了更好的帮助理解,再举一个最简单的例子:
int copy_add(int x, int y)
{
return x + y;
}
int nocopy_add(int& x, int& y)
{
x += y;
return x;
}
以上两个函数都实现了对输入的两个int类型值进行相加并且返回的功能,第一个函数式比较纯粹的函数,符合我们上面所说的函数式编程的特点。再看第二个函数,它将入参设为引用(在项目中,为了减少值对象拷贝的性能消耗,常把入参设为引用),这就带来了问题——入参很容易在函数内部被改变。
在著作《Functional Programming in C++》(非常推荐此书)中给出了关于函数式编程的定义:
Functional programming is a style of programming that emphasizes the evaluation of expressions, rather than execution of commands. The expressions in these languages are formed by using functions to combine basic values. A functional language is a language that supports and encourages programming in a functional style.
简单来说:在OOP(面向对象编程)中,正如大多数人做的那样,更多的考虑是算法的步骤,即对对象的处理。而在函数式编程里你需要学会如下的思考方式:什么是输入,什么是输出,还有需要执行哪些转换将两者映射起来。
函数式编程
在介绍了函数编程之后,我们尝试使用其思想来解决实际的问题:假如有个vector保存着文件中的所有单词,需要统计其所有单词出现的频率,并且按照评率高低输出对应单词。最传统的命令式编程大概会这么写:
void print_word(vector<string>& words) {
unordered_map<string, int> wordCount;
for (auto&& s : words) {
unordered_map<string, int>::iterator iter = wordCount.find(s);
if (iter == wordCount.end()) {
wordCount.insert({
s, 1});
} else {
wordCount[s]++;
}
}
vector<pair<int, string>> reverseword;
for (auto it = wordCount.begin(); it != wordCount.end(); ++it) {
reverseword.emplace_back(make_pair(it->second, it->first));
}
sort(reverseword.begin(), reverseword.end(), [](const pair<int, string>& lhs, const pair<int, string>& rhs) {
return lhs.first > rhs.first;
}); // 高阶函数
for (auto& p : reverseword) {
cout << "word is " << p