C++ 模板

C++ 模板是一种强大的泛型编程工具,它允许我们编写通用的代码,可以用于处理多种不同的数据类型。模板允许我们在编写代码时将类型作为参数进行参数化,从而实现代码的重用性和灵活性。

在 C++ 中,模板由关键字 template 开始,并且后面跟着模板参数列表。模板参数可以是类型参数或非类型参数。

1、模板的基本语法

1.1 类型模板参数(函数模板)

类型模板参数允许我们在定义模板时指定一个或多个类型参数,这些类型参数可以在模板的定义中使用。例如,下面是一个简单的模板函数示例:

template <typename T>
T add(T a, T b) {
return a + b;
} int main() {
std::cout << add<int>(1,1); // 输出:2 显示指定模板参数类型
std::cout << add(1.1, 2.2); // 输出:3.3 自动推导模板参数类型为浮点型 return 0;
}

在这个例子中,T 是类型模板参数,它代表一个占位符类型。我们可以在模板函数 add 中使用 T 来进行参数和返回类型的声明。当我们调用 add 函数时,编译器会根据传入的实际类型来推断 T 的值。

1.2 非类型模板参数(类模板)

非类型模板参数允许我们在定义模板时指定一个或多个非类型参数,这些参数可以是整数、枚举、指针或引用。非类型参数的值在编译时确定,且在模板的每个实例化中都是常量。例如,下面是一个使用非类型参数的模板类示例:

template <int Size>
class Array {
private:
int data[Size];
public:
// 构造函数
Array() {
for (int i = 0; i < Size; ++i) {
data[i] = i;
}
} void print() const {
for (int i = 0; i < Size; i++) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
}; int main() {
Array<5> arr5;
Array<10> arr10;
arr5.print();// 输出:0 1 2 3 4
arr10.print();// 输出:0 1 2 3 4 5 6 7 8 9
return 0;
}

在这个例子中,Size 是非类型模板参数,它代表数组的大小。我们可以在模板类 Array 的定义中使用 Size 来声明数组的大小,并在构造函数中初始化数组。

2、模板作用及优势

模板在 C++ 中具有重要的作用和优势,可以提高代码的重用性和灵活性

2.1.代码重用:

模板允许我们编写通用的代码,可以处理多种不同的数据类型,而无需为每种类型编写重复的代码。下面是一个模板函数示例,用于计算数组的总和:

#include <iostream>

template <typename T, size_t Size>
T sumArray(T (&arr)[Size]) {
T sum = T();
for (size_t i = 0; i < Size; ++i) {
sum += arr[i];
}
return sum;
} int main() {
int intArray[] = {1, 2, 3, 4, 5};
double doubleArray[] = {1.1, 2.2, 3.3, 4.4, 5.5}; int intSum = sumArray(intArray);
double doubleSum = sumArray(doubleArray); std::cout << "Sum of intArray: " << intSum << std::endl;
std::cout << "Sum of doubleArray: " << doubleSum << std::endl; return 0;
}

在这个示例中,我们定义了一个模板函数 sumArray,它可以接受任意类型的数组作为参数,并计算数组的总和。通过使用模板,我们可以在不修改代码的情况下重复使用这个函数,适用于不同类型的数组。

2.2.类型安全:

模板在编译时进行类型检查,可以提供更好的类型安全性。下面是一个模板类示例,用于实现一个简单的栈数据结构:

#include <iostream>
#include <vector> template <typename T>
class Stack {
private:
std::vector<T> stack; public:
void push(const T& item) {
stack.push_back(item);
} T pop() {
if (stack.empty()) {
throw std::runtime_error("Stack is empty");
}
T item = stack.back();
stack.pop_back();
return item;
} bool isEmpty() const {
return stack.empty();
}
}; int main() {
Stack<int> intStack;
intStack.push(10);
intStack.push(20);
intStack.push(30); while (!intStack.isEmpty()) {
std::cout << intStack.pop() << " ";
}
// 输出: 30 20 10 std::cout << std::endl; Stack<std::string> stringStack;
stringStack.push("Hello");
stringStack.push("World"); while (!stringStack.isEmpty()) {
std::cout << stringStack.pop() << " ";
}
// 输出: World Hello return 0;
}

在这个示例中,我们定义了一个模板类 Stack,它可以存储任意类型的元素。通过使用模板,我们可以在编译时检查类型的一致性,并避免将错误类型的元素推入栈中。

3、C++中的模板与 Java中的泛型的异同

C++中的模板和 Java中的泛型都是泛型编程的概念,它们都可以用于编写通用的代码,以便在多个类型上重复使用。

3.1.相同点

  1. 都可以使用泛型来编写通用的代码,以便在多个类型上重复使用。

  2. 都允许在编译时进行类型检查,以避免在运行时出现类型错误。

  3. 都可以使用类型参数来表示通用的类型。

3.2.主要不同点

  1. 语法不同:C++中的模板使用template关键字来声明模板参数,而 Java中的泛型使用<>符号来声明类型参数。

  2. 支持的类型不同:在C++中,模板可以使用任何可用的类型,包括内置类型和自定义类型,而在 Java中,泛型不能接受基本类型作为类型参数――它只能接受引用类型。这意味着可以定义 List<Integer>,但是不可以定义 List<int>

  3. C++中,参数类型不同,实例类型也不同。而在 Java中,不管类型参数是什么,所有实例都是同一类型,并且类型参数会在运行时被抹去。即,尽管在编译时 ArrayList<String>ArrayList<Integer> 是两种类型,但是在运行时只有ArrayList被加载到 JVM中。

  4. Java中,在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但是在静态方法中不能使用类的泛型(因为类的泛型在创建对象时,即实例化时才指定,而静态方法要早于对象的创建,此时类的泛型还没指定而静态结构已经需要使用了)。C++中,类型参数可以用于静态方法和静态变量

.....

综上所述,虽然C++中数模板和 Java中的泛型都是泛型编程的概念,但它们在实现上有很大差异。

参考资料:

【C++基础语法】

https://blog.csdn.net/hxhxhxhxx/article/details/119334165

【C++模板和泛型详解】

https://blog.csdn.net/jj6666djdbbd/article/details/127155728

【C++泛型和 Java泛型的异同】

https://blog.csdn.net/cnds123/article/details/130778765

https://blog.csdn.net/coding_is_fun/article/details/81564512

C++模板介绍的更多相关文章

  1. Django框架(十一):模板介绍、模板语言、模板继承、HTML转义

    1. 模板介绍 1.1 模板的功能 产生html,控制页面上展示的内容.模板文件不仅仅是一个html文件. 模板文件包含两部分内容: 静态内容:css.js.html. 动态内容:用于动态去产生一些页 ...

  2. puppet的使用:ERB模板介绍

    ERB介绍 全称是Embedded RuBy,意思是嵌入式的Ruby,是一种文本模板技术,用过JSP的话,会发现两者语法很像. 我们项目中一般用ERB来产生各模块的配置文件.ERB模板也可以用来产生W ...

  3. [Vue 牛刀小试]:第十七章 - 优化 Vue CLI 3 构建的前端项目模板(1)- 基础项目模板介绍

    一.前言 在上一章中,我们开始通过 Vue CLI 去搭建属于自己的前端 Vue 项目模板,就像我们 .NET 程序员在使用 asp.net core 时一样,我们更多的会在框架基础上按照自己的开发习 ...

  4. laravel blade模板介绍

    第一步:首先写好模板 在sites下新建立一个app.blade.php文件 写入模板如: <!DOCTYPT html><html><head> <titl ...

  5. phpcmsv9更换模板介绍

    先分享下大概的步骤: 1.上传模版文件到服务器:2.在站点管理 里边[模板风格配置]选择新模板:3.设置不同模型对应模板:4.修改现有的栏目,匹配新模板:5.更新栏目缓存.系统缓存,更新HTML静态页 ...

  6. Instruments模板介绍(更新中...)

    第一章.Instruments(仪器)快速入门 Instruments可以用来收集关于一个或者多个系统进程的性能和行为的数据,并跟踪睡着时间产生的数据.它提供了好几个分析模板: Blank 任何类型都 ...

  7. Win10系列:VC++ Direct3D模板介绍2

    (3)CreateDeviceResources函数 CreateDeviceResources函数默认添加在CubeRenderer.cpp源文件中,此函数用于创建着色器和立体图形顶点.接下来分别介 ...

  8. Win10系列:VC++ Direct3D模板介绍1

    Visual Studio为开发Direct3D应用程序提供了便捷的模版,读者可以不必手动去新建Direct3D中所使用到的基础资源,而只需专注于图形的绘制.本小节主要为读者介绍这个模版中用于绘制图形 ...

  9. discuz模板介绍

    1.discuz目录下template为模板目录 模板套系 discuz每套模板,支持不同的风格,而多个风格组成一套套系. 推荐使用复制的方法创建新的风格 (*默认的公共页面静态资源,存储在discu ...

  10. DataUml Design 教程5-代码模板介绍(甚于T4模板技术)

    DataUml Design 代码模板全然基于C#语言来编写的. 不懂写模板的能够请教作者,随时欢迎. 以下是一段模板代码,这段代码能够获取一个类结构的全部信息.             <#@ ...

随机推荐

  1. 代码随想录算法训练营Day28 回溯算法 | 491.递增子序列 46.全排列 47.全排列 II

    代码随想录算法训练营 491.递增子序列 题目链接:491.递增子序列 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2. 示例: 输入: [4, 6, 7, 7] ...

  2. 代码随想录算法训练营Day24 回溯算法| 理论基础 77. 组合

    代码随想录算法训练营 回溯 什么是回溯法 回溯法也可以叫做回溯搜索法,它是一种搜索的方式. 在二叉树系列中,我们已经不止一次,提到了回溯,例如二叉树:以为使用了递归,其实还隐藏着回溯. 回溯是递归的副 ...

  3. Spring Boot 自动配置一篇概览

    一.什么是自动配置 bean 自动配置类通过添加 @AutoConfiguration 注解实现. 因为 @AutoConfiguration 注解本身是以 @Configuration 注解的,所以 ...

  4. 在国内用Java代理调用OpenAI的ChatGPT的API接口

    第一步:一个科学友好的上网工具,开启全局代理: 第二步:一个注册好的ChatGPT账号,且在个人设置里面生成apiKey:https://platform.openai.com/account/api ...

  5. 曲线艺术编程 coding curves 第五章 谐波图形(谐振图形) HARMONOGRAPHS

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http:// ...

  6. Python获取系统当前时间并进行类型转换

    # 1.使用Python获取系统当前时间print('---------下面是方法1-----------')import timeprint(time.strftime('%Y-%m-%d %H:% ...

  7. C++面试八股文:override和finial关键字有什么作用?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第22面: (二师兄好苦逼,节假日还在面试...) 面试官:C++的继承了解吗? 二师兄:(不好意思,你面到我的强项了..)了解一些. 面试官:什么是 ...

  8. Self-Instruct 论文解读:利用大模型自己给自己生成指令数据,指令数据自动生成

    总览 大规模"指令调整"的语言模型,即指令微调的LLM,已经表现出非凡的零样本能力,尤其是推广新任务上. 然而,这些模型严重依赖于人类编写的指令数据,而这些数据通常在数量.多样性和 ...

  9. 行行AI人才直播第7期:奇计AI创始人左晟《AI时代的商业挑战和机遇》

    行行AI人才是博客园和顺顺智慧共同运营的AI行业人才全生命周期服务平台,是园子商业化努力的一个重要方向. 行行AI人才直播希望以直播的方式让大家更多了解AI行业的现状与未来可能的发展方向. 随着人工智 ...

  10. Elasticsearch日常开发

    2020-08-12 14:51:37 每次遇到ES开发,一般都是查询es里面的数据,今天我教大家一个简单的es的查询.废话不多说,直接上代码. 在pom文件中引入 <dependency> ...