小工具知识网

当前位置: 首页 > 行业知识 > 【c++】模板进阶

行业知识

【c++】模板进阶

2026-11-07 18:34:09 来源:互联网转载

> 作者���介:დ旧言~,目前大二,现在学习Java,c,c++,Python等

> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:了解非类型模板参数,熟练使用模板的特化。

> 毒鸡汤:你活得不快乐的原因是:既无法忍受目前的状态,又没能力改变这一切。

> 望小伙伴们点赞收藏✨加关注哟 

前言  

早期我们学习了模板,只能说浅学,很多重要的知识点都没有讲解,今天我们来深度讲解模板。

⭐主体

学习模板的进阶我们按照下面的图解来学习:

非类型模板参数

模板参数分为: 类型形参与非类型形参

  1. 类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称后面
  2. 非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

类型形参:

// T: 类型模板参数,它是一个类型template  class A;

非类型形参:

// T: 类型模板参数,它是一个类型// N: 非类型模板参数,它是一个常量template  class A;

实例举例:

#define N 10template // 静态栈class Stack {private:T _a[N];size_t _top;};void test(){Stack st1; // 10Stack st2; // 10}

问题分析:

现在实现了一个静态栈,可以存 10 个数据,实例化的每个对象都可以存 10 个数据,如果我想要第一个对象 st1 存 100 个数据,第二个对象存 200 个数据,这种结构就非常的不好。

问题解决:

此时就需要用到非类型模板参数了

template // 静态栈class Stack {private:T _a[N];size_t _top;};void test(){Stack st1; // 100Stack st2; // 200}

注意事项:

  • 浮点数、类对象以及字符串是不允许作为非类型模板参数的
  • 非类型的模板参数必须在编译期就能确认结果

    (因为模板是在编译阶段就要实例化的,而模板必须要知道实例化成的具体类型之后才能实例化,

    因此非类型模板参数和类型模板参数一样,必须在编译阶段就能够确认实例化成的具体类型才可以,

    否则编译阶段无法完成实例化,链接阶段就找不到实例化出的具体的类,进而发生链接错误)

    模板的特化

    通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理,比如:实现了一个专门用来进行小于比较的函数模板。

    问题探讨

    比如:交换两个元素

    templatevoid Swap(T& x, T& y){    T tmp(x); x = y; y = tmp;}void test(){    int x = 1, y = 2;    Swap(x, y);    vector v1 = { 1, 2, 3, 4 };    vector v2 = { 10, 20, 30, 40 };    Swap(v1, v2); // 深拷贝式交换,代价太大,效率低}

    解决方案一:函数的匹配原则,写一个专门针对 vector 类型对象交换的函数:推荐这种

    // 函数匹配原则,专门针对 vector 类型对象交换的函数 -- 推荐这种void Swap(vector& v1, vector& v2){    v1.swap(v2); // 只需要交换对象内部的几个指针即可}

    解决方案二:函数模板的特化,针对 vector 类型对象的交换进行特殊化处理:

    // 函数模板的特化(针对某些具体类型进行特殊化处理) -- 最后还是要经过模板推演templatevoid Swap(vector& v1, vector& v2){    v1.swap(v2);}

    问题拓展:

    此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。模板特化分为:函数模板特化与类模板特化。

    函数特化步骤

    函数模板的特化步骤:

    1. 必须要先有一个基础的函数模板。
    2. 关键字 template 后面接一对空的尖括号
    3. 函数名后跟一对尖括号 ,尖括号中指定需要特化的类型。
    4. 函数形参表:必须要和 中指定的类型完全相同,如果不同,编译器可能会报一些奇怪的错误。

    小试牛刀:

    template  // 基础函数模板void add(T1& x, T2& y){cout 

上一篇:怎么删除服务器地址信息?

下一篇:MATLAB - 模型预测控制(MPC)控制入门 —— 设计并仿真 MPC 控制器