首页 > 编程语言 >C++模板介绍

C++模板介绍

时间:2023-09-12 16:12:08浏览次数:52  
标签:Java 介绍 泛型 参数 C++ 类型 模板

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

标签:Java,介绍,泛型,参数,C++,类型,模板
From: https://www.cnblogs.com/ForestCherry/p/17696476.html

相关文章

  • Lnton羚通视频分析算法平台关于泥石流山体滑坡视觉监控识别检测算法介绍
    Lnton羚通的算法算力云平台是一款出色的解决方案,具备突出的特点。该平台提供高性能、高可靠性、高可扩展性和低成本的功能,使用户能够高效地执行各种复杂的计算任务。此外,平台还提供了丰富的算法库和工具,支持用户上传和部署自定义算法,提高了平台的灵活性和个性化能力。泥石流和山体......
  • CNN简单介绍及基础知识
    前言在过去的几年里,卷积神经网络(CNN)引起了人们的广泛关注,尤其是因为它彻底改变了计算机视觉领域,它是近年来深度学习能在计算机视觉领域取得突破性成果的基石。它也逐渐在被其他诸如自然语言处理、推荐系统和语音识别等领域广泛使用。在这里,主要从三个方面介绍CNN, (1)CNN历史发展......
  • c++高精度模板
    #include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<string>#include<vector>#include<list>usingnamespacestd;constintmaxn......
  • 最长上升子序列----nlogn算法-模板
    #include<iostream>#include<vector>#defineMAX1010usingnamespacestd;vector<int>len;//这里我返回的满足len[k]>=val[i]且k最小的位置//和上文红色部分的描述是等价的,只是变成了更新len[k],而不是len[k+1]intbisearch(intval){intleft=0,right=len.size(......
  • 高精度加减法模板
    正整数+-法#include<stdio.h>#include<string.h>voidplus(char*a,char*b,char*c);voidminus(char*a,char*b,char*c);voidminus(char*a,char*b,char*c){ inti,j,k; intla=strlen(a); intlb=strlen(b); intflag=0; memset(c,0......
  • a^b%c问题 ---模板
    (1)ABmodC.(1<=A,B<2^62,1<=C<=10^9)http://acm.bit.edu.cn/mod/programming/view.php?a=530快速幂----二分#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>usingnamespacestd;longlongquickpow(......
  • 树状数组--模板
    #include<stdio.h>#include<string.h>#defineN50050intn;intin[N];intLowbit(intt){ returnt&(-t);}intSum(intp){ intsum=0; while(p>0) { sum+=in[p]; p-=Lowbit(p); } returnsum;}voidplus(intp,intnum){ while(......
  • dijkstra 模板
    Input输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time分钟;(1=<(a,b)<=1000;a,b之间可能有多条路)接着的第T+1行有S个数,表示和草儿家相连的城市;接着的第T+2行......
  • 古罗马--模板
    计算古罗马加法,输入不合法,则输出“Aha!Idon'tneedtocalculatethesum”。 测试用例1以文本方式显示I↵I↵以文本方式显示II↵1秒64M0#include<stdio.h>#include<string.h>#include<stdlib.h>charp[5][11][10];voiddabiao(){ memset(p,0,sizeof(p)); st......
  • 最长上升子序列 ---模板
    #include<stdio.h>#include<string.h>intn;intp[100000];intdp[100000];intmain(){ inti,j,k; while(scanf("%d",&n)!=EOF){ for(i=1;i<=n;i++) scanf("%d",&p[i]); memset(dp,0,sizeof(dp)); dp[1]=1; ......