Functional C++ for Fun Profit

Lambda Conf上有人讲C++函数式编程。

在Functional Conf 2019上,就有主题为“Lambdas: The Functional Programming Companion of Modern C++”的演讲。

演讲者介绍了现代C++中函数式编程相关内容,讲解了如何使用Lambda表达式编写符合函数式编程原则的C++代码,以及C++语言的演变等内容。

NDC Conferences上也有相关演讲,主题为“Functional C++ for Fun & Profit”。

演讲探讨了函数式编程与C++的交集,从C++11中Lambda表达式的引入开始,研究了函数式编程的核心原则,以及如何在C++开发中有效应用这些原则。

 

函数式编程

 

函数式编程是一种编程范式,核心思想是将计算过程视为数学函数的组合,强调函数的纯粹性和数据的不可变性,避免副作用(如修改外部状态、改变变量值等)。

特点包括:

- 不可变数据:数据一旦创建就不能被修改,若需变更,需生成新的数据副本,减少状态混乱。


- 纯函数:输入决定输出,不依赖外部状态,也不产生副作用(如修改全局变量、IO操作等),相同输入始终返回相同结果,便于测试和并行计算。


- 函数是一等公民:函数可以像变量一样被传递、赋值、作为参数或返回值,支持高阶函数(如接收或返回其他函数)。


- 避免状态变化:通过函数组合而非循环或状态修改来实现逻辑,常用递归代替迭代。

例如,在处理列表时,函数式编程会用 map (映射)、 filter (过滤)等纯函数组合操作,而非通过循环修改列表元素。

常见的函数式编程语言有Haskell、Scala、Erlang等,现代主流语言(如Java、C++、Python)也逐渐引入了函数式特性(如Lambda表达式、不可变集合)。

 

代码示例

 

用现代C++特性(Lambda、算法库)处理数据,体现“用函数组合实现逻辑”“避免修改状态”的特点:

#include <iostream>
#include <vector>
#include <algorithm> // 提供函数式算法
#include <numeric>   // 提供accumulate

int main() {
// 原始数据(不可修改,体现不可变性)
const std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 1. 过滤:保留偶数(用lambda作为筛选条件)
std::vector<int> evens;
std::copy_if(numbers.begin(), numbers.end(), 
std::back_inserter(evens),
[](int n) { return n % 2 == 0; }); // 纯函数:输入决定输出

    // 2. 转换:偶数乘以2(用lambda映射)
std::vector<int> doubled;
std::transform(evens.begin(), evens.end(),
std::back_inserter(doubled),
[](int n) { return n * 2; }); // 无副作用的转换

    // 3. 聚合:计算总和(用accumulate组合结果)
int sum = std::accumulate(doubled.begin(), doubled.end(),
0, // 初始值
[](int total, int n) { return total + n; });

    // 输出结果:2+4+6+8+10的两倍之和 → (2+4+6+8+10)*2 = 60
std::cout << "结果: " << sum << std::endl; // 仅此处有副作用(IO)
return 0;
}


函数式特点说明:

- 不可变数据: numbers 被声明为 const ,全程不修改原始数据。
- 纯函数:所有Lambda表达式(如 n%2==0 、 n*2 )都只依赖输入,无外部状态。


- 函数作为参数: copy_if 、 transform 等算法接收Lambda函数作为参数,体现“函数是一等公民”。


- 无显式循环:用标准库算法替代 for 循环,逻辑更接近“做什么”而非“怎么做”。

运行结果为 60 ,整个过程通过函数组合完成数据处理,避免了手动修改变量状态。

 


优缺点

 

好处

 

1. 代码更易理解和维护

纯函数无副作用,逻辑独立,相同输入始终返回相同结果,代码意图更清晰,减少了因状态变化导致的“隐藏逻辑”。

2. 天然支持并发和并行

不可变数据避免了多线程中的“资源竞争”(无需加锁),纯函数可安全地在多线程中并行执行,适合分布式和高性能场景。

3. 便于测试和调试

纯函数不依赖外部状态,单元测试时无需复杂的环境准备,只需验证输入输出;调试时也无需追踪变量的状态变化历史。

4. 代码复用性强

函数作为“一等公民”可被灵活组合(如通过 map / filter / reduce ),形成新的功能,减少重复代码。

5. 减少错误

不可变性避免了意外修改数据导致的bug(如“一个地方改了,别处跟着错”),尤其在复杂系统中更明显。

 

坏处

 

1. 学习曲线较陡

思维方式与常见的命令式编程(如用 for 循环、修改变量)差异大,理解递归、函数组合、Monad等概念需要时间。

2. 性能开销可能更高

不可变数据每次修改需创建副本,对于大型数据(如大列表)可能增加内存占用和计算成本(尽管现代语言有优化)。

3. 处理IO等副作用时较繁琐

纯函数禁止IO(如读写文件、网络请求),需通过特殊机制(如Haskell的IO Monad)封装副作用,代码可能更复杂。

4. 不适合所有场景

对于需要频繁修改状态的场景(如GUI交互、游戏帧更新),函数式的“不可变”思路可能反直觉,实现效率低。

5. 调试栈可能更复杂

大量函数组合和递归可能导致调用栈较深,调试时追踪问题源头相对麻烦。

 

总结

 

函数式编程适合复杂业务逻辑、高并发、分布式系统等场景,能提升代码可靠性和可维护性;但在性能敏感、IO密集、状态频繁变化的场景中,可能不如命令式编程直接高效。现代主流语言(如C++、Python)多采用“混合范式”,兼顾两者优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915183.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915183.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python基础理论与实践:从零到爬虫实战

引言Python如轻舟&#xff0c;载你探寻数据宝藏&#xff01;本文从基础理论&#xff08;变量、循环、函数、模块&#xff09;启航&#xff0c;结合requests和BeautifulSoup实战爬取Quotes to Scrape&#xff0c;适合零基础到进阶者。文章聚焦Python基础&#xff08;变量、循环、…

ThingJS开发从入门到精通:构建三维物联网可视化应用的完整指南

文章目录第一部分&#xff1a;ThingJS基础入门第一章 ThingJS概述与技术架构1.1 ThingJS平台简介1.2 技术架构解析1.3 开发环境配置第二章 基础概念与核心API2.1 核心对象模型2.2 场景创建与管理2.3 对象操作基础第三章 基础开发实战3.1 第一个ThingJS应用3.2 事件系统详解3.3 …

关于list

1、什么是listlist是一个带头结点的双向循环链表模版容器&#xff0c;可以存放任意类型&#xff0c;需要显式定义2、list的使用有了前面学习string和vector的基础&#xff0c;学习和使用list会方便很多&#xff0c;因为大部分的内容依然是高度重合的。与顺序表不同&#xff0c;…

Mysql 查看当前事务锁

在 MySQL 中查看事务锁&#xff08;锁等待、锁持有等&#xff09;&#xff0c;可以使用以下方法&#xff1a; 一、查看当前锁等待情况&#xff08;推荐&#xff09; SELECTr.trx_id AS waiting_trx_id,r.trx_mysql_thread_id AS waiting_thread,r.trx_query AS waiting_query,b…

【Keil5-map文件】

Keil5-map文件■ map文件■ map文件

k8s 基本架构

基于Kubernetes(K8s)的核心设计&#xff0c;以下是其关键基本概念的详细解析。这些概念构成了K8s容器编排系统的基石&#xff0c;用于自动化部署、扩展和管理容器化应用。### 一、K8s核心概念概览 K8s的核心对象围绕容器生命周期管理、资源调度和服务发现展开&#xff0c;主要包…

Bell不等式赋能机器学习:微算法科技MLGO一种基于量子纠缠的监督量子分类器训练算法技术

近年来&#xff0c;量子计算&#xff08;Quantum Computing&#xff09; 和 机器学习&#xff08;Machine Learning&#xff09; 的融合成为人工智能和计算科学领域的重要研究方向。随着经典计算机在某些复杂任务上接近计算极限&#xff0c;研究人员开始探索量子计算的独特优势…

Edge浏览器设置网页自动翻译

一.浏览网页自动翻译设置->扩展->获取Microsoft Edge扩展->搜索“沉浸式翻译”->获取 。提示&#xff1a;如果采用其他的翻译扩展没找自动翻译功能&#xff0c;所以这里选择“沉浸式翻译”二.基于Java WebElement时自动翻译Java关键代码&#xff1a;提示&#xff1…

TCP/UDP协议深度解析(四):TCP的粘包问题以及异常情况处理

&#x1f50d; 开发者资源导航 &#x1f50d;&#x1f3f7;️ 博客主页&#xff1a; 个人主页&#x1f4da; 专栏订阅&#xff1a; JavaEE全栈专栏 本系列往期内容~ TCP/UDP协议深度解析&#xff08;一&#xff09;&#xff1a;UDP特性与TCP确认应答以及重传机制 TCP/UDP协议深…

R 基础语法

R 基础语法 R 语言是一种针对统计计算和图形表示而设计的编程语言&#xff0c;广泛应用于数据分析、统计学习、生物信息学等领域。本文将为您介绍 R 语言的基础语法&#xff0c;帮助您快速入门。 1. R 语言环境搭建 在开始学习 R 语言之前&#xff0c;您需要安装并配置 R 语言环…

语义熵怎么增强LLM自信心的

语义熵怎么增强LLM自信心的 一、传统Token熵的问题(先理解“痛点”) 比如模型回答“阿司匹林是否治疗头痛?”→ 输出“是” 传统Token熵:只看“词的概率”,比如“是”这个词的概率特别高(Token熵0.2,数值低说明确定性强 )。 但实际风险:医学场景里,“是”的字面肯定…

javaweb的几大常见漏洞

CTF javaweb中几大常见漏洞(基于java-security靶场) 对于CTF而言&#xff0c;java类型的题目基本都是白盒代码审计&#xff0c;在java类型的web题目增长的今天&#xff0c;java代码审计能力在ctf比赛中尤为重要。 这篇博客主要是给大家介绍一下一些常见漏洞在java代码里面大概是…

【设计模式C#】外观模式(用于解决客户端对系统的许多类进行频繁沟通)

一种结构性设计模式。特点是将复杂的子系统调用逻辑封装到一个外观类&#xff0c;从而使客户端更容易与系统交互。优点&#xff1a;简化了接口的调用&#xff1b;降低了客户端与子系统的耦合度&#xff1b;封装了子系统的逻辑。缺点&#xff1a;引入了额外的类&#xff0c;可能…

【PTA数据结构 | C语言版】二叉堆的快速建堆操作

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将 n 个顺序存储的数据用快速建堆操作调整为最小堆&#xff1b;最后顺次输出堆中元素以检验操作的正确性。 输入格式&#xff1a; 输入首先给出一个正整数 c&#xff08;≤1…

【数据结构初阶】--双向链表(二)

&#x1f525;个人主页&#xff1a;草莓熊Lotso &#x1f3ac;作者简介&#xff1a;C研发方向学习者 &#x1f4d6;个人专栏&#xff1a; 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言&#xff1a;生活是默默的坚持&#xff0c;毅力是永久的…

vue-cli 模式下安装 uni-ui

目录 easycom 自定义easycom配置的示例 npm安装 uni-ui 准备 sass 安装 uni-ui 注意 easycom 传统vue组件&#xff0c;需要安装、引用、注册&#xff0c;三个步骤后才能使用组件。easycom将其精简为一步。 只要组件路径符合规范&#xff08;具体见下&#xff09;&#…

JavaSE-接口

概念在Java中&#xff0c;接口可以被看成是一种公共规范&#xff0c;是一种引用数据类型。语法1.接口的定义格式与类的定义格式基本相同&#xff0c;将class关键字替换为interface关键字&#xff1a;public interface IShape {}2.类与接口之间使用implements关键字来实现接口&a…

常用类学习

文章目录字符串相关的类String的特性String对象的创建字符串相关的类String类与其他结构之间的转换StringBuffer,StringBuilderStringBuffer类的常用方法JDK8之前日期时间APIjava.lang.System类java.util.Date类java.text.SimpleDateFormat类java.util.Calendar类JDK8中新日期时…

【Python库包】Gurobi-Optimize (求解 MIP) 安装

目录Step1&#xff1a;注册账号Step2&#xff1a;获取Licence另&#xff1a;完整安装 Gurobi软件参考本博客简介Gurobi-Optimizer的安装&#xff08;Python 环境&#xff09;。 Step1&#xff1a;注册账号 官网-Gurobi-Optimizer ⚠️注意&#xff1a; Gurobi 是商业软件&…

【渗透测试】NmapScanHelper 扫描辅助工具

目录NmapScanHelper 扫描辅助工具一、功能特性二、文件说明三、使用方法1. 安装依赖macOSUbuntu/DebianCentOS/RHEL2. 配置网段3. 运行扫描基本用法常用端口扫描示例扫描模式特殊环境模式选择性扫描自定义文件4. 查看结果四、扫描模式说明标准模式特殊环境模式五、支持的 Nmap …