当前位置: 首页 > news >正文

【C++】C++11(可变参数模板、lambda表达式、包装器)

文章目录

  • 1. 可变参数模板
    • 1.1 介绍
    • 1.2 emplace系列接口实现
  • 2. lambda表达式
    • 2.1 语法介绍
    • 2.2 原理
  • 3. 包装器
  • 4. bind

在这里插入图片描述

1. 可变参数模板

1.1 介绍

可变参数我们在C语言阶段已经了解过了,C语言中叫做可变参数列表,其中使用 ... 代表可变参数。
C语言中的可变参数列表链接

由于C++中增加了模板,因此C++11中就引进了可变参数模板,其能够创建可以接受可变参数的函数模板和类模板,相比C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进。

C++中的可变参数模板延续了C语言中可变参数列表中 ... 的使用。

下面就是一个基础的可变参数的函数模板

在这里插入图片描述
上面的参数args前面有省略号,所以它就是一个可变模版参数,我们把带省略号的参数称为“参数包”,它里面包含了0到N(N>=0)个模版参数。

注意使用方式:

  • template<class ...Args> ,作为模板参数包时,...在前,
  • Args... args,作为函数形参参数包时,...在后
  • 函数参数args进行传递时,应这样传递,args...,…在args的后面

我们可以使用sizeof...(args)检查参数的个数

在这里插入图片描述

那我们能不能显示参数包中的数据呢?

在这里插入图片描述
注意:解析模板参数包是在编译时做的,上述代码是在运行时,所以是不可能显示出来的。

我们无法直接获取参数包args中的每个参数的,只能通过展开参数包的方式来获取参数包中的每个参数,这是使用可变模版参数的一个主要特点,也是最大的难点,即如何展开可变模版参数。
由于语法不支持使用args[i]这样方式获取可变参数,所以我们的用一些其它方式获取参数包的值。

  • 递归函数方式展开参数包

在这里插入图片描述
这样就可以一一进行打印了。

  • 逗号表达式展开参数包

在这里插入图片描述

这种展开参数包的方式,不需要通过递归终止函数,是直接就地展开的, PrintArg不是一个递归终止函数,只是一个处理参数包中每一个参数的函数。

这种就地展开参数包的方式实现的关键是逗号表达式。

  • 逗号表达式:(printarg(args), 0),也是按照这个执行顺序,先执行printarg(args),再得到逗号表达式的结果0。
  • 同时还用到了C++11的另外一个特性——初始化列表,通过初始化列表来初始化一个变长数组。
  • {(printarg(args), 0)…}将会展开成((printarg(arg1),0), (printarg(arg2),0), (printarg(arg3),0), etc… ),最终会创建一个元素值都为0的数组int arr[sizeof…(Args)]
  • 由于是逗号表达式,在创建数组的过程中会先执行逗号表达式前面的部分printarg(args)打印出参数,也就是说在构造int数组的过程中就将参数包展开了,这个数组的目的纯粹是为了在数组构造的过程展开参数包。

1.2 emplace系列接口实现

学习完可变参数模板后,我们就可以试着来实现以下STL中容器的emplace系列接口。

这里我们就以list为例,我们看到它不仅使用了可变参数模板,而且使用了万能引用。

在这里插入图片描述

在这里插入图片描述

注意:尽管emplace_back是可变参数模板,但是它不支持插入多个值

在这里插入图片描述

那它支持可变模板参数是干什么的呢?

对于多参数的,例如一个pair类型,无论是使用push_back还是emplace_back插入一个pair对象,二者没有区别,都是构造pair+拷贝/移动构造

但是对于没有pair对象的第三种情况而言,它把构造pair的参数作为可变参数包直接往下传,不断地传;直到传到链表节点那个地方使用pair的参数直接去构造节点,没有了“中间商”,因此只有一个构造。

在这里插入图片描述

因此我们emplace_back可以按照下面的方式写,对于未使用对象操作,仅使用构造对象的参数进行传参的,都直接构造

参数传递时注意右值的退化,合理使用完美转发!

在这里插入图片描述

在这里插入图片描述

emplace_back高效原因总结:

  • 原地构造emplace_back 允许在容器内部直接构造元素,而不需要先创建一个临时对象,然后再将其复制或移动到容器中。这避免了额外的复制或移动操作,从而提高了效率。
  • 优化构造函数调用:使用 emplace_back 时,可以直接传递构造函数的参数给容器,而不是先构造一个完整的对象。这允许编译器优化构造函数的调用,例如通过完美转发来减少不必要的拷贝和移动操作。
  • 避免拷贝/移动构造函数和析构函数的调用:对于需要在容器中添加大量复杂对象时,emplace_back 通过直接构造对象,避免了临时对象的拷贝或移动构造函数的调用,同时也避免了在容器销毁时这些临时对象的析构函数调用。这可以显著提高性能,尤其是在对象构造、析构或拷贝/移动操作开销较大时。
  • 与 std::move 相比的优势:虽然 std::move 可以与 push_back 结合使用以减少拷贝开销,但它仍然需要构造一个临时对象(尽管是一个右值引用),然后再将其移动到容器中。相比之下,emplace_back 直接在容器内部构造对象,完全避免了临时对象的创建。

综上所述,emplace_back 通过在容器内部直接构造元素,减少了拷贝/移动操作,优化了内存使用,并避免了不必要的构造函数和析构函数调用,从而提供了比 push_back 更高效的元素添加方式。在可能的情况下,优先使用 emplace_back 可以显著提升性能。

2. lambda表达式

在C++98中,如果想要对一个数据集合中的元素进行排序,可以使用std::sort方法。

int main()
{int array[] = { 4,1,8,5,3,7,0,9,2,6 };// 默认按照小于比较,排出来结果是升序size_t sz = sizeof(array) / sizeof(array[0]);sort(array, array + sz );// 如果需要降序,需要改变元素的比较规则sort(array, array + sz, greater<int>());return 0;
}

对于自定义类型的数据,需要自己定义比较规则。
在这里插入图片描述
随着C++语法的发展,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法,都要去写一个类并在类中实现仿函数,如果每次比较的逻辑不一样,还要去实现多个类和仿函数,特别是相同类的命名,这些都给编程者带来了极大的不便。因此,在C++11语法中出现了Lambda表达式。

2.1 语法介绍

lambda表达式书写格式:[捕捉列表] (参数列表) mutable -> 返回值类型 { 函数体 }。它的结构类似于函数,唯独没有函数名

  • 捕捉列表:该列表总是出现在lambda函数的开始位置,编译器根据[ ]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
  • 参数列表:与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略
  • mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
  • 返回值类型:用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
  • 函数体:在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。
  1. 简单的lambda表达式

对于捕捉列表和mutable我们稍后在描述,先简单写一个lambda看一看。
在这里插入图片描述
尽管返回值类型可以省略,但是还是推荐写上。

现在我们就可以使用lambda改造上面排序的比较规则
在这里插入图片描述

这样直接在当前位置写是不是就清爽很多,不必再像以前一样先写个类,然后重载operator()了

在这里插入图片描述
通过上述例子可以看出,lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量

  1. 捕捉列表

mutable可以取消其常量性

在这里插入图片描述

  • 传值捕捉,我们发现其实a,b在外部并未被交换

在这里插入图片描述

所以我们必须要了解捕获列表说明:

捕捉列表描述了上下文中哪些数据可以被lambda使用,以及使用的方式传值还是传引用

  • [var]:表示值传递方式捕捉变量var
  • [=]:表示值传递方式捕获所有父作用域中的变量(包括this)
    • 父作用域指包含lambda函数的语句块
  • [&var]:表示引用传递捕捉变量var
  • [&]:表示引用传递捕捉所有父作用域中的变量(包括this)
  • [this]:表示值传递方式捕捉当前的this指针
  • 传引用捕捉

在这里插入图片描述

  • 所有值都传值捕捉

在这里插入图片描述

  • 所有值都传引用捕捉

在这里插入图片描述

  • 混合使用(捕捉列表可由多个捕捉项组成,并以逗号分割

在这里插入图片描述

在这里插入图片描述

注意:

  • 捕捉列表不允许变量重复传递,否则就会导致编译错误
    在这里插入图片描述
  • 在块作用域中的lambda函数仅能捕捉父作用域中局部变量或全局变量,捕捉任何非此作用域或者非局部变量都会导致编译报错在这里插入图片描述
  • lambda表达式之间不能相互赋值,即使看起来类型相同
    在这里插入图片描述

2.2 原理

我们先使用重载operator()和lambda写同一个功能,观察底层实现

class Rate
{
public:Rate(const double& rate):_rate(rate){}double operator()(double money, int year){return   money * _rate * year;}
private:double _rate;
};int main()
{//使用类对象重载的operator()double rate = 0.015;Rate r1(rate);cout << r1(10000, 2) << endl;//使用lambdaauto func = [=](double money, int year)->double {return money * rate * year; };cout << func(10000, 2) << endl;return 0;
}

从使用方式上来看,函数对象与lambda表达式完全一样。

函数对象将rate作为其成员变量,在定义对象时给出初始值即可,lambda表达式通过捕获列表可以直接将该变量捕获到,然后通过传参传进去

在这里插入图片描述

我们查看汇编代码可以发现,实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()。

3. 包装器

  • function包装器

function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。
那么我们来看看,我们为什么需要function呢?

到目前位置,我们知道的可调用对象有:函数指针、仿函数、lambda表达式三种,下面我们就用这三种来实现三个不同的函数。

template<class F, class T>
T Transfer(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}
//函数指针
double f(double i)
{return i / 2;
}
//仿函数
struct Functor
{double operator()(double d){return d / 3;}
};int main()
{// 函数名cout << Transfer(f, 66.6) << endl << endl;// 函数对象(仿函数)cout << Transfer(Functor(), 66.6) << endl << endl;// lamber表达式cout << Transfer([](double d)->double { return d / 4; }, 66.6) << endl << endl;return 0;
}

我们都知道,静态变量在一个语句块中是同一个,但是下面的代码中却不是。显然它们调用的不是同一个Transfer,由于这里模板的原因,编译器在底层会根据不同的函数模板实例化出不同的Transfer函数,导致效率低下

在这里插入图片描述

同时,如果我们要把可调用对象存储到一个容器中,那容器元素的类型是什么呢?函数指针、仿函数还是lambda表达式?很显然都不行。

为了解决这个问题,C++11引入了std::function包装器,它可以将这些不同类型的可调用对象(参数、返回值相同)封装成统一的类型,使得函数模板和容器等可以更加灵活地处理这些对象。

包装器的语法比较怪,使用它需要包含对应的头文件functional;其次它是一个类,类的模板参数和平常的不一样。
在这里插入图片描述
在这里插入图片描述

还可以使用包装器包装类的成员函数:

在这里插入图片描述

使用包装器包装后,就无需再实例化多个Transfer函数,此时不同类型的可调用参数对象都是同一种类型了。

在这里插入图片描述

包装器的应用

题目链接:逆波兰表达式

右边的代码使用包装器使代码更加的灵活

在这里插入图片描述

4. bind

bind函数定义在头文件functional中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表

一般而言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M一般小于N)参数的新函数。同时,使用std::bind函数还可以实现参数顺序调整等操作。

一句话总结:bind可以调整一个可调用对象的参数的个数和顺序

原型如下:
在这里插入图片描述
该函数的参数

  • Fn:可调用对象
  • 可变参数模板Args:要么是值,要么是placeholder(一个命名空间)

在这里插入图片描述

  • 调整参数的顺序(不常用)

在这里插入图片描述

  • 调整参数个数(常用)

绑定某些参数,其余参数通过调用时传递

在这里插入图片描述

对于调整参数的个数而言,更加适合下面这种场景,可以简化调用

在这里插入图片描述
在这里插入图片描述

相关文章:

【C++】C++11(可变参数模板、lambda表达式、包装器)

文章目录 1. 可变参数模板1.1 介绍1.2 emplace系列接口实现 2. lambda表达式2.1 语法介绍2.2 原理 3. 包装器4. bind 1. 可变参数模板 1.1 介绍 可变参数我们在C语言阶段已经了解过了&#xff0c;C语言中叫做可变参数列表&#xff0c;其中使用 ... 代表可变参数。 C语言中的可…...

矩阵获客时代,云微客让你一个人成就一支队伍

短视频利用大家碎片化的时间让自身得到广泛的应用和发展&#xff0c;因此很多公司纷纷布局短视频赛道。但是一个账号的曝光量有限&#xff0c;并且能够出的爆款视频更是少之又少&#xff0c;这个时候就需要增加账号的数量&#xff0c;布局形成账号矩阵。 做账号矩阵&#xff0c…...

浅谈基础的图算法——Tarjan求强联通分量算法(c++)

文章目录 强联通分量SCC概念例子有向图的DFS树代码例题讲解[POI2008] BLO-Blockade题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 思路AC代码 【模板】割点&#xff08;割顶&#xff09;题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示…...

【Godot4自学手册】第四十四节用着色器(shader)实现溶解效果

本小节&#xff0c;我将自学用用着色器&#xff08;shader&#xff09;实现溶解效果&#xff0c;最终效果如下&#xff1a; 一、进行shader初始设置 首先我们进入Player场景&#xff0c;选择AnimatedSprite2D节点&#xff0c;在检查器中找到CanvasItem属性&#xff0c;并在M…...

【画流程图工具】

画流程图工具 draw.io draw.io&#xff08;现称为 diagrams.net&#xff09;是一款在线图表绘制工具&#xff0c;可以用于创建各种类型的图表&#xff0c;如流程图、网络图、组织结构图、UML图、思维导图等。以下是关于它的一些优点、应用场景及使用方法&#xff1a; 优点&a…...

Revit二次开发选择过滤器,SelectionFilter

过滤器分为选择过滤器与规则过滤器 规则过滤器可以看我之前写的这一篇文章: Revit二次开发在项目中给链接模型附加过滤器 选择过滤器顾名思义就是可以将选择的构件ID集合传入并加入到视图过滤器中,有一些场景需要对某些构件进行过滤选择,但是没有共同的逻辑规则进行筛选的情况…...

【Linux】进程概念—环境变量

目录 一、冯诺依曼体系结构 二、操作系统(Operator System) 1 .概念 2 .设计OS的目的 3 . 定位 4 . 系统调用和库函数概念 三、进程 1 .基本概念 2 .描述进程-PCB&#xff08;process control block&#xff09;进程控制块 3 . 组织进程 4 . 查看进程 5 .通过系统调用获取进程…...

第十二章 Spring MVC 框架扩展和SSM框架整合(2023版本IDEA)

学习目标 12.1 Spring MVC 框架处理JSON数据12.1.1 JSON数据的传递处理12.1.2 JSON数据传递过程中的中文乱码和日期问题12.1.3 多视图解析器 12.2 Spring MVC 框架中的数据格式转换12.2.1 Spring MVC 框架数据转换流程12.2.2 编写自定义转换器12.2.3 使用InitBinder装配自定义编…...

js中的全局函数有这些

js中的全局函数有这些,记忆规则 6个编译 escape、‌‌unescape、decodeURI、decodeURIComponent、encodeURI、encodeURIComponent 2个数据处理 Number()、String() 4个数字处理 ‌isFinite、isNaN、‌parseFloat、parseInt 1个特殊情况 eval()...

Android SurfaceFlinger——重绘闪烁处理(四十六)

在帧数据准备完成后,下一步是调用 devOptRepaintFlash() 函数处理显示输出设备的可选重绘闪烁问题,这里我们就来看一下重绘闪屏问题的处理方案。 1.更新输出设备的色彩配置文件2.更新与合成相关的状态3.计划合成帧图层4.写入合成状态5.设置颜色矩阵6.开始帧7.准备帧数据以进行…...

罗马数字转整数 C++

罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#x…...

Day20_2--介绍同步加载和异步加载

同步加载和异步加载是处理程序或数据的两种不同方式&#xff0c;它们在处理任务的方式、效率和用户体验上有显著差异。下面是对这两种加载机制的详细介绍。 1. 同步加载&#xff08;Synchronous Loading&#xff09; 定义&#xff1a; 同步加载是一种加载数据或资源的方式&am…...

sftp做成一个池子

前言&#xff1a;开发中的需求要去对方的 ftp 服务器下载文件&#xff0c;这里下载文件采用 ftp 方式&#xff0c;下载之后程序再去解析文件的内容&#xff0c;然后再存数据库。下载过来的文件默认是 zip 格式&#xff0c;需要解压 unzip 一下&#xff0c;然后里面有一个 csv 文…...

全网最全-Netty从入门到精通

XiaoYongCai/2024/8/6 一&#xff1a;Netty入门 1.Netty概述 A.Netty的定义 Netty是一个提供异步事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。在Java领域&#xff0c;Netty被认为是除了Java原生NIO之外的最佳网络…...

C#知识|文件与目录操作:对象的创建、保存、读取

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 面向对象编程的特点就是一切皆对象&#xff0c;操作的也是对象&#xff0c;本节学习文件与目录操作中&#xff0c;对象的保存&#xff1b; 以下为学习笔记。 01 对象的特点 ①&#xff1a;对象运行在内存中&#xff…...

自定义 SwiftUI 中符号图像的外观

文章目录 前言大小颜色渲染模式单色分层调色板多色 可变值设计变体示例代码结论 前言 符号图像是来自 Apple的SF Symbols 库的矢量图标&#xff0c;设计用于在 Apple 平台上使用。这些可缩放的图像适应不同的大小和重量&#xff0c;确保在我们的应用程序中具有一致的高质量图标…...

循环神经网络和自然语言处理一

目录 一.分词 1.分词工具 2.分词的方法 3.N-gram表示方法 二.向量化 1.one-hot编码 2.word embedding 3.word embedding API 4.数据形状改变 既然是自然语言&#xff0c;那么就有字&#xff0c;词&#xff0c;句了 一.分词 1.分词工具 tokenization&#xff0c;jie…...

CSS技巧专栏:一日一例 20-纯CSS实现点击会凹陷的按钮

本例图片 案例分析 其实这个按钮非常的简单啊,主要就是利用了box-shadow的inset。 布局代码 <button class="base">凹下的按钮</button> 基础样式 :root{--main-bg-color: #dcdcdc; /* 将页面背景色调整为浅灰色 */--color:#000;--hover-color:#99…...

20240807 每日AI必读资讯

&#x1f468;‍&#x1f4bc;马斯克再发难、OpenAI 高层巨变&#xff1a;两大核心人物离职&#xff0c;总裁休长假到年底 - OpenAI 联合创始人 John Schulman 官宣离职&#xff0c;加入原是竞品公司的 Anthropic - 陪伴 OpenAI 共同成长 9 年的总裁兼联合创始人 Greg Brockm…...

海外社媒账号如何让防关联?账号隔离的5大要点

在跨境电商迅速发展和全球化营销的背景下&#xff0c;海外社交媒体平台成为外贸人拓展市场的关键阵地。因此&#xff0c;为了保障账号安全&#xff0c;实现高效推广&#xff0c;账号隔离以及安全防关联对外贸人来说至关重要。本文将盘点引起海外社媒账号关联的原因及其五大解决…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...

手动给中文分词和 直接用神经网络RNN做有什么区别

手动分词和基于神经网络&#xff08;如 RNN&#xff09;的自动分词在原理、实现方式和效果上有显著差异&#xff0c;以下是核心对比&#xff1a; 1. 实现原理对比 对比维度手动分词&#xff08;规则 / 词典驱动&#xff09;神经网络 RNN 分词&#xff08;数据驱动&#xff09…...