[C++] 模板进阶:特化与编译链接全解析
文章目录
- 非类型模板
- 类型形参
- 非类型模板参数
- 代码示例
- **模板的特化**
- 为什么要有模板的特化
- 函数模板特化
- 使用场景与示例
- 函数模板特化的实现细节
- 类模板特化
- 全特化
- 示例
- 偏特化
- 部分优化
- 通过进一步限制模板参数进行特化
- 偏特化为指针类型示例:
- 偏特化为引用类型示例:
- 特化测试结果分析
- 模板特化中的注意事项
- 实例化时严格的匹配性
- 指针特化时`const`的修饰问题
- 为什么在参数列表使用`const`?
- `const`与指针修饰关系
- **指针本身是常量** (`const`在`*`之后)
- **指向的内容是常量** (`const`在`*`前面)
- 指针特化时`const`修饰的应用
- 已经特化的类中`T`表示为什么?
- 模板的分离编译
- 分离编译模式简介
- 模板的分离编译
- 分离编译测试
- 原因解析
- C/C++程序的编译链接原理
- 为什么不能分离定义?


非类型模板
模板参数分为:类型形参和非类型形参
类型形参
类型形参,即在模板初阶中所用的例如class A
或typename A
此类参数类型,跟在class
或typename
后。
[C++] 模版初阶-CSDN博客
非类型模板参数
非类型模板参数,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用,定义方法如下:
template<class T, size_t N = 10>
注意:
- 非类型模板参数只能是整型。
- 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
- 非类型的模板参数必须在编译期就能确认结果(原因看下文)。
代码示例
template<int N>
class Array {
public:int arr[N];// 其他方法
};
Array<5> myArray; // 创建一个包含5个元素的数组对象
模板的特化
为什么要有模板的特化
模板技术提供了强大的泛型编程能力,使得我们能够编写与数据类型无关的代码,从而提高代码的复用性和灵活性。然而,在实际应用中,有时需要对特定类型进行特殊处理,这时就需要用到模板特化。
**注意:**一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出
模板特化的出现是为了解决模板在处理某些特殊类型时可能遇到的问题。例如,一个通用的比较函数模板可以比较大多数类型的数据,但在遇到指针时,仅比较指针的地址而不是指向的内容,这就可能导致错误的结果。模板特化允许为特定类型提供定制的实现,以解决这些特殊情况下的需求。
// 例如日期类中的函数模板的使用,在使用指针比较的时候就会出现错误,这时候就需要进行模板特化
template<class T>
bool Less(T left, T right)
{return left < right;
}Date d1(2022, 7, 7);
Date d2(2022, 7, 8);
cout << Less(d1, d2) << endl; // 可以比较,结果正确Date* p1 = &d1;
Date* p2 = &d2;
cout << Less(p1, p2) << endl; // 可以比较,结果错误
当使用指针进行比较的时候比较的就是指针指向的地址,而地址是从栈上向下申请,所以不会按照原本日期类希望的排序方法进行排序。
此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化与类模板特化
函数模板特化
函数模板特化用于为特定类型定制函数实现。它的典型用处是在普通模板无法满足某些类型需求时提供特定的功能。特化函数的签名必须与原模板函数完全一致。
函数模板的特化步骤:
- 必须要先有一个基础的函数模板;
- 关键字
template
后面接一对空的尖括号<>
;- 函数名后跟一对尖括号,尖括号中指定需要特化的类型;
- 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇
怪的错误。
使用场景与示例
紧接上面的错误案例:假设我们有一个通用的比较函数模板Less
,它比较两个对象的大小
template<typename T>
bool Less(T left, T right) {return left < right;
}
上述模板在大多数情况下都能正常工作,但如果传入的是指针类型,那么比较的将是指针的地址而非指向的对象。为了正确比较指针指向的内容,我们需要对指针类型进行特化:
template<>
bool Less<Date*>(Date* left, Date* right) {return *left < *right;
}
此特化版本用于比较指针指向的Date
对象,确保比较逻辑正确。
函数模板特化的实现细节
在实现函数模板特化时,需要注意以下几点:
- 特化声明:模板特化的声明需要紧随
template<>
,然后是函数签名,特化的类型需要放在尖括号中。 - 参数一致性:特化函数的参数列表必须与原模板函数保持一致,不能增加或减少参数,也不能更改参数的顺序或类型。
**注意:**推荐直接写一个函数实现特殊处理,编译器在处理的时候会优先调用更匹配的。
类模板特化
类模板特化比函数模板特化更加复杂,主要分为全特化和偏特化。类模板特化的主要作用是为特定类型提供定制的类定义和实现。
全特化
全特化是指将模板参数列表中的所有参数都具体化(全特化版本中的所有参数都必须指定具体类型)。
示例
假设我们有一个通用的数据存储类模板Data
,它可以存储两个不同类型的对象:
template<typename T1, typename T2>
class Data {
public:Data() { std::cout << "Data<T1, T2>" << std::endl; }
private:T1 _d1;T2 _d2;
};
我们可以为特定的类型组合如int
和char
进行全特化:
template<>
class Data<int, char> {
public:Data() { std::cout << "Data<int, char>" << std::endl; }
private:int _d1;char _d2;
};
在这个全特化版本中,我们为Data
类提供了一个int
和一个char
类型的特化实现。这意味着当我们创建Data<int, char>
类型的对象时,将调用特化版本的构造函数。
偏特化
偏特化是部分特化的形式,可以仅对部分模板参数进行特化。偏特化比全特化更灵活,允许特化的同时保留一些模板参数。
偏特化中有两种表现方式:部分特化、通过限制参数进行特化
部分优化
部分特化允许开发者针对特定的模板参数进行特化,而其他模板参数保持泛型(需要在template
中声明)。这样可以在不影响通用模板行为的情况下,为某些特定类型或类型组合提供专门的实现。
示例:
template<typename T1, typename T2>
class Pair {
public:Pair(T1 first, T2 second) : first_(first), second_(second) {}T1 first() const { return first_; }T2 second() const { return second_; }private:T1 first_;T2 second_;
};
上述模板类是通用的,可以存储任意类型的两个数据。然而,如果我们需要对第一类型是int
的情况进行特化,可以使用部分特化:
template<typename T2>
class Pair<int, T2> {
public:Pair(int first, T2 second) : first_(first), second_(second) {}int first() const { return first_; }T2 second() const { return second_; }void setFirst(int value) { first_ = value; } // 额外的特化方法private:int first_;T2 second_;
};
在这个部分特化版本中,我们特化了Pair
模板的第一个类型为int
,第二个类型保持泛型。这样,当Pair<int, T2>
的对象创建时,将调用这个特化版本,而不是通用版本。
通过进一步限制模板参数进行特化
偏特化为指针类型示例:
当需要模板参数为指针类型的时候,可以对其进行特化,以实现针对于指针的特定逻辑。这在需要对指针执行特定操作(如解引用、比较等)时尤为有用。
// 两个参数偏特化为指针类型
template <typename T1, typename T2>
class Data<T1*, T2*> {
public:Data() { std::cout << "Data<T1*, T2*>" << std::endl; }
private:T1 _d1;T2 _d2;
};
- 模板特化:
Data<T1*, T2*>
,这个偏特化版本对模板的两个参数T1
和T2
进行了特化,使得它们必须是指针类型。 - 实现细节:在构造函数中打印了一条消息,标识这是指针特化的版本。
- 成员变量:特化类中的成员变量依然是
T1
和T2
类型,不过它们实际上是指针指向的对象的类型。
偏特化为引用类型示例:
对于引用类型的参数,我们可以通过特化来处理那些需要传递引用的情况。这在需要修改外部对象或避免对象复制时非常有用。
// 两个参数偏特化为引用类型
template <typename T1, typename T2>
class Data<T1&, T2&> {
public:Data(const T1& d1, const T2& d2): _d1(d1), _d2(d2) {std::cout << "Data<T1&, T2&>" << std::endl;}
private:const T1& _d1;const T2& _d2;
};
- 模板特化:
Data<T1&, T2&>
,这个偏特化版本对模板的两个参数T1
和T2
进行了特化,使得它们必须是引用类型。 - 实现细节:在构造函数中接受了
T1
和T2
类型的引用,并初始化类的成员变量。 - 成员变量:特化类中的成员变量是对传入对象的常量引用
const T1&
和const T2&
,这确保了数据不会被意外修改。
特化测试结果分析
void test2() {Data<double, int> d1; // 调用全特化的模板Data<int, double> d2; // 调用基础的模板Data<int*, int*> d3; // 调用特化的指针版本Data<int&, int&> d4(1, 2); // 调用特化的引用版本
}
Data<double, int> d1;
:调用了全特化模板,因为参数类型既不是指针也不是引用。Data<int, double> d2;
:同样调用全特化模板。Data<int*, int*> d3;
:调用了特化的指针版本,因为两个参数都是指针类型。Data<int&, int&> d4(1, 2);
:调用了特化的引用版本,因为两个参数是引用类型(注意,这里初始化引用类型参数时传递的是常量1
和2
,这些字面量会被隐式转换为合适的引用类型)。
模板特化中的注意事项
实例化时严格的匹配性
模板编程中,模板实例化时的匹配性要求非常严格,即使已经对模板进行了特化,在实例化时也必须精确匹配到最合适的模板版本。这种严格的匹配性体现在以下几个方面:
- 全特化:指的是为特定类型组合提供一个完全定制化的实现。全特化要求在实例化时完全匹配所有模板参数类型,只有在参数完全匹配时,才会使用该特化版本。
- 偏特化:允许对部分模板参数进行特化,同时保持其他参数的泛型性。在实例化时,编译器会优先选择最匹配的特化版本。如果没有找到完全匹配的特化版本,编译器才会退而求其次,选择更加通用的版本。
- 模板匹配顺序:编译器在选择模板实例化时,会按照以下优先顺序进行匹配:
- 完全匹配的全特化(优先级最高)
- 最匹配的偏特化
- 最通用的模板
指针特化时const
的修饰问题
为什么在参数列表使用const
?
防止修改传入的参数:特化版本中的
Date* const& left
和Date* const& right
,通过使用const
,函数保证不会修改传入的指针变量本身的值,即指针的指向保持不变。这是一种安全措施,避免函数对外部数据的不必要的修改。
const
与指针修饰关系
指针本身是常量 (const
在*
之后)
当const
放在指针符号*
之后时,它修饰的是指针本身,这意味着指针的值(即它指向的内存地址)不能被改变。但指针指向的对象的内容可以改变。
Date* const pDate;
在这个例子中,pDate
是一个常量指针,它指向一个Date
类型的对象。pDate
本身不能指向别处,但是pDate
指向的Date
对象的内容是可以修改的。
通过特化时将
**const**
放在在*****
之后即可解决在特化中的修饰关系。
指向的内容是常量 (const
在*
前面)
当const
放在*
前面时,它修饰的是指针指向的对象,这意味着不能通过这个指针修改指向的对象的内容,但指针本身可以指向不同的对象。
const Date* pDate;
在这个例子中,pDate
是一个指向Date
对象的指针。虽然pDate
本身可以指向不同的Date
对象,但不能通过pDate
来修改它所指向的对象的内容。
指针特化时const
修饰的应用
通用函数模板
template<class T>
bool LessFunc(const T& left, const T& right)
{return left < right;
}
该函数模板中的const
修饰的是传入的left
和right
不会被改变。
特化函数模板
template<>
bool LessFunc<Date*>(Date* const& left, Date* const& right)
{return *left < *right;
}
**Date* const& left**
和**Date* const& right**
:这两个参数都是指向Date
对象的常量指针的引用。这意味着:
- 指针本身不可改变:函数内部不能改变
left
和right
指向的地址(与通用模板中的修饰目的相同)。
为了保持与通用模板中const
效果相同,因此写为Date* const& left
。通用模板是为了是传入的数据不被修改,而对于传入的指针来说,**const**
放在*****
之后,表示指针本身是常量。换句话说,指针本身的地址不能改变,也就是说,一旦初始化后,指针不能指向其他地址,也就是传入的指针不能被修改了,和通用模板实现的效果相同。
因此,Date* const&
的意思是“指向Date
对象的常量指针的引用”。这个引用在函数内不会改变其所引用的指针对象,也不能通过引用修改指针本身的指向。
已经特化的类中T
表示为什么?
在已经特化过的类中,不管特化时是将原类型特化为指针类型或者引用类型之类的,在类中使用T
的时候一律会按照原类型进行使用,也就是说如果在类中要用原类型的指针类型的话,还是需要用T*
。
如此表示在const
修饰传参时也有用处,例如上文所理解的LessFunc<Date*>(Date* const& left, Date* const& right)
,如果特化为指针的类中Date
实际表示为Date*
的话,那么在修饰的时候究竟要如何修饰呢。此时就会产生语法与习惯上的矛盾,所以将T
直接作为原类型使用会更加方便与顺手。
模板的分离编译
分离编译模式简介
分离编译是软件工程中的一个基本概念,它指的是将源代码分割成多个模块,每个模块独立编译,最后通过链接器将这些模块组合成最终的可执行文件。这种方式提高了编译的并行性,同时也使得代码维护更加简单,因为修改一个模块通常不会影响到其他模块的编译。
模板的分离编译
分离编译测试
我们有一个模板函数Add
,它的声明和定义被分别放在不同的文件中:
// a.h
template<class T>
T Add(const T& left, const T& right);// a.cpp
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
在main.cpp
中,我们使用了Add
函数的两个实例:
#include "a.h"int main()
{Add(1, 2); // 整数实例Add(1.0, 2.0); // 浮点数实例return 0;
}
此时当运行的时候会出现链接错误。
原因解析
C/C++程序的编译链接原理
C/C++程序的构建过程通常分为四个阶段:预处理、编译、汇编和链接。
- 预处理:预处理器处理
#include
指令和其他预处理器指令,将头文件的内容插入到源文件中,同时处理宏定义等。 - 编译:编译器将预处理后的源代码转换成汇编代码。在这个阶段,编译器检查语法、词法和语义错误,并且如果一切正确,将代码转换成机器可以理解的指令集。
- 汇编:将汇编代码转换为机器代码的二进制形式。
- 链接:链接器将多个目标文件(.obj)和库文件链接起来,解决符号引用问题,生成最终的可执行文件。
为什么不能分离定义?
**原因:**模板实例化的代码并不是编译的时候在模板位置直接生成的,而是在需要实例化的时候才会生成特定的具体代码。
- 实例化时机:模板的实例化发生在编译器遇到模板函数或类的使用时。如果模板的定义不在编译器当前正在处理的编译单元中,那么编译器无法知道如何实例化模板,因此不会生成相应的函数代码。
- 地址问题:如你提到的例子,当在
a.cpp
中没有Add模板的具体实例化代码时,编译器不会生成对应的函数。而在main.obj
中尝试使用Add<int>
和Add<double>
时,链接器会在链接阶段寻找这些函数的地址,但因为它们在编译时没有被生成,所以链接器找不到这些地址,导致链接错误。- 单定义规则(One Definition Rule,ODR):C++的单定义规则要求每个非内联函数或变量在一个程序中只能有一个定义。模板的每次实例化都被视为一个独立的函数或类型定义,这意味着每次实例化都必须在同一个编译单元中完成,否则可能会违反ODR。
- **推荐做法:**将模板的声明和定义放在同一个头文件中,确保在任何包含该头文件的编译单元中都可以进行正确的实例化。
相关文章:

[C++] 模板进阶:特化与编译链接全解析
文章目录 非类型模板类型形参非类型模板参数代码示例 **模板的特化**为什么要有模板的特化函数模板特化使用场景与示例函数模板特化的实现细节 类模板特化全特化示例 偏特化部分优化通过进一步限制模板参数进行特化偏特化为指针类型示例:偏特化为引用类型示例&#…...
oracle-备份
1、逻辑备份(exp) /ljbb/oracle/o19c/bin/exp hr/hr tablesJOBS file/ljbb/bak/system.sql log/ljbb/bak/ststem.log query\where deptno30\ buffer100000000 hr/hr 用户/密码 tablesJOBS 表名:JOBS file/ljbb/bak/system.sql 备份文件路径 log/ljbb/ba…...
oracle 并行parallel的插入insert用法
在Oracle数据库中,INSERT 语句确实可以使用 Parallel(并行)功能。通过并行插入,可以在插入数据时同时利用多个并行操作进程来执行插入操作,从而显著提高插入操作的速度和效率。这对于需要处理大量数据插入的场景尤为有…...
夜莺监控使用指南
夜莺监控使用指南 本文用于解决在部署和应用夜莺监控中遇到的一些问题以及官方文档缺失的某些步骤可能会遇到的坑。 安装过程 我使用是NightingaleCategrafPrometheus的架构。 Nightingale安装文档:https://flashcat.cloud/docs/content/flashcat-monitor/night…...

MySQLDM笔记-查询库中是否存在列出的表名及查询库中列出的不存在的表名
如下表名: aaa,bb,cc,ccs,dds,csdf,csdfs,sdfa,werwe,csdfsd 在MySQL库中,查询哪些表名在数据库中 SELECT table_name FROM information_schema.tables WHERE table_schema your_database_name_here AND table_name IN (aaa, bb, cc, ccs, dds, csdf…...

第9天 xxl-job
使用xxl-job需要建表 引入依赖 添加配置 Bean public XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor new XxlJobSpringExecutor();xxlJo…...
C++字符串<string>库
一:string及其标准库 C中使用string类需要添加<string>库。 string初始化: string str1 "Hello"; string str2; str2 "World"; string str3 str1 str2; string在变量的声明以及初始化与C语言的char类字符串一致。但是str…...

智能分析,安全无忧:AI视频分析技术在安全生产中的深度应用
在当今快速发展的科技时代,视频智能分析技术(Intelligent Video Analysis,简称IV)已经成为提升安全生产水平的重要手段。这一技术通过计算机图像视觉分析技术,实现了对场景中目标的自动识别和追踪,有效提升…...

02 Canal的安装使用
1 下载Canal Cannal下载地址如下:https://github.com/alibaba/canal/releases,这里选择Canal 1.1.4版本下载。2 上传解压 #首先创建目录 “/software/canal” [rootnode3 ~]# mkdir -p /software/canal#将Canal安装包解压到创建的canal目录中 [rootnode3 ~]# tar …...

【网络安全】玲珑安全第四期
鉴于玲珑安全漏洞挖掘前三期课程取得的优异成绩和获得的强烈反响,我们决定启动玲珑安全第四期漏洞挖掘培训计划。 文章目录 往期学员收获基础学员报喜(部分)课程反馈第四期课程课程内容免费课程往期学员收获 第一期课程总结及学员收获:->点我查看第一期学员收获<- …...

【工具】图片背景移除界面 UI 源码
移除图片背景的UI 照片背景移除和填充颜色的用户界面 仓库地址:https://github.com/MengWoods/remove-background-ui/tree/main 介绍 该项目提供了一个基于 removebg 库的用户界面,用于从输入的照片中移除背景,并用不同的颜色填充背景。 …...

CentOS linux 安装openssl(openssl拒绝服务漏洞【CVE-2022-0778】解决)
一、安装 1.下载相关openssl包 下载地址: https://www.openssl.org/source/ 2.将下载好的压缩包放到 /app/server/nginx 路径下(根据自己实际需求定义) 3.切换至该路径 cd /app/server/nginx4.压缩包解压 压缩包解压 :tar -…...

假如有一个嵌套集合,怎么通过stream流将集合放到一个集合之中?
假如有一个嵌套集合,怎么通过stream流将集合放到一个集合之中? 问题解释:你有一个嵌套的集合,想要通过 Stream 流的方式将其中嵌套的集合放到一个新的集合中。可以使用 flatMap 方法来实现。这种方法非常适合处理嵌套集合的情况。…...
flutter doctor出现 Unable to find bundled Java version
在安装flutter时执行flutter doctor时出现了如下错误: [!] Android Studio (version 2022.1) ✗ Unable to find bundled Java version. 解决办法 检查下Applications/Android Studio.app/Contents目录下有没有jre文件夹,如果没有则创建一个&…...
Linux系统修改root密码
疑难杂症篇(十六)--虚拟机出现“The system is running in low-graphics mode“问题的解决方案_the system is running in low graphic-CSDN博客...

AI时代,我们还可以做什么?
最近看了本书,书名叫做《拐点:站在 AI 颠覆世界的前夜》,作者是万维钢。 本想着看完后,就能掌握一整套 AI 技巧,结果——竟然学了很多道理。 这本书讨论了以下话题: 我们该怎么理解这个 AI 大时代的哲学&am…...

【生成式人工智能-十-文字、图片、声音生成策略】
人工智能生成文字、图片、声音的方法 生成的本质生成的策略文字AR (Autoregressive Generation)图像和视频 NAR(Non-Autoregressive Generation)解决NAR生成品质低的问题 AR NAR 生成的本质 文字、图像、声音的生成的本质,就是给模型一个输入,模型把基…...
git pull 注意事项
当在执行 git pull 操作并且涉及到合并操作时,Git 会打开默认的文本编辑器(在这种情况下是 nano),以便你编写合并提交(merge commit)消息。这个消息将记录在合并提交中,解释为什么进行了这次合并…...

拥抱变革:旗晟智能巡检机器人系统重塑高风险行业巡检模式
随着工业自动化的快速发展,特别是在石油、化工、煤矿等高风险行业中,传统的巡检方式已难以满足现代企业的需求。高频次、全天候、重复的人工巡检不仅效率低下,还面临着人身安全、数据准确性和运营成本等多方面的挑战。针对这些问题࿰…...

监听器——监听着我们WEB项目中的域对象
监听器 ——它监听着我们WEB项目中的域对象 何时被创建被销毁 ServlertContextListener——它监听ServletContext对象的创建和销毁 contextInitialized 创建的时候会调用 Tomcat启动时调用 contextDestroyed销毁的时候自动会调用的方法 Tomcat终止 这两个方法中携带的参数S…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...