C++中的模板及其特化相关知识(详细完整)

[C++ Template]深入模板--特化与重载 目录 第12章 特化与重载 12.2 重载函数模板 12.2.1 签名 12.2.2 重载的函数模板的局部排序 12.2.3 正式的排序原则 12.2.4 模板和非模板 12.3 显式特化 12.3.1 全局的类模板特化 12.3.2 全局的函数模板特化 12.3.3 全局成员特化 12.4 局部的类模板特化 第12章 特化与重载 目前为止,我们已经知道了:C++模板如何... 阅读详情

模板

  • 模板是将一个事物的结构规律予以固定化、标准化的成果,它体现的是结构形式的标准化。

C++与模板

  • 利用模板的思想是泛型编程—即不考虑具体数据类型的编程方式,即功能相同时,不需要重复编写代码
  • 模板是建立通用的与数据类型无关的算法的重要手段。C++国际标准ISO 14882将模板正式引入标准库,要求用模板类取代传统C++中定义的类。
  • c++集合了过程式语言,通用语言,面向对象语言的众多特点。模板是通用语言的特性,模板又叫参数化类型(parametrized types)。

看一个例子:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

//模板函数
template<typename T>
void M_add(T x1, T x2) {
    cout << x1 << " + " << x2 << " = " << num1 + num2 << endl;
}


//模板类
template<typename T>
class M_Class {
public:
    static void multi(T x1, T x2) {
        cout << x1 << " + " << x2 << " = " << num1 * num2 << endl;
    }
};


int main() {
    //整型
    int x1 = 1;
    int x2 = 2;
    M_add<int>(x1, x2);   //模板函数实例
    M_Class<int>::multi(x1, x2);   //模板类实例
    //浮点型
    double num3 = 3.1;
    double num4 = 4.2;
    M_add<double>(num3, num4);    //模板函数实例
    M_Class<double>::multi(num3, num4);  //模板类实例
    return 0;
}

其中的void M_add(T x1, T x2) 为模板函数,class M_Class为模板类

C++中的函数模板

  1. 函数模板是一组函数的抽象描述,它不是一个实实在在的函数,函数模板 不会编译成任何目标代码。函数模板必须先实例化成模板函数,这些模板函 数再程序运行时会进行编译和链接,然后产生相应的目标代码。简单来说,函数模板就是实现代码的重用,图个省事。
  2. 函数模板的关键字为template
  3. 模板的定义。以下是模板定义的一般格式:
template <class any>//class 也可以换成typename,后者是新来的。
void swap(any &a,any &b)
{
......
}

调用时,就像调用普通函数那样调用模板函数,之后的工作编译器会为你摆平。比如:swap(x,y);

  • 在使用函数模板时有两种方式
    • 自动类型推到调用 Swap(a, b)
    • 具体类型显示调用 Swap(a, b)
template < class T>
 void max(T& x,T& y)  //函数模板
 {  
 	cout <<((x>y)?x:y);  
 }
 void func(int i,int j)  
 {
 	max(i,j);  //自动推到调用
 	max<int>(i,j);  //具体类型显示调用
 }
  • 函数模板的错误使用
 template < class T>
 void max(T& x,T& y)  //函数模板
 {  
 	cout<<((x>y)?x:y);  
 }
 void func(int i,char j)  //正常的函数
 {
 	max(i,i);  //实例化的模板函数,正确调用
 	max(i,j);  //实例化的模板函数,但错误调用
 }

上面例子中第二个实例化的模板函数出现了错误:在这里插入图片描述
这是因为在实例化的过程中要按照声明时的要求进行,函数模板声明了两个形参是同一类型,第二个函数的参数i为int类型而j为char类型,所以编译产生错误,函数模板是不允许隐式类型转换的,调用时类型必须严格匹配

  • 多参数调用
    函数模板还可以定义任意多个不同的类型参数,但是对于多参数函数模板:
    • 编译器是无法自动推导返回值类型的
    • 可以从左向右部分指定类型参数
#include <iostream>
 
using namespace std;
 
template <typename T1, typename T2, typename T3>
T1 add(T2 a, T3 b)
{
    T1 ret;
    ret = static_cast<T1>(a + b);
    return ret;
}
 
void main()
{
    int c = 12;
    float d = 23.4;
    //cout << add(c, d) << endl;	//error,无法自动推导函数返回值
    cout << add<float>(c, d) << endl;	//返回值在第一个类型参数中指定
    cout << add<int, int, float>(c, d) << endl;
    system("pause");
}
  • 函数模板跟普通函数一样,也可以被重载
    • C++编译器优先考虑普通函数
    • 如果函数模板可以产生一个更好的匹配,那么就选择函数模板
    • 也可以通过空模板实参列表<>限定编译器只匹配函数模板
      限定用法:func<>(x,y); (使用时)
#include <iostream>

using namespace std;

//函数模板
template < class T>
 void max(T& x,T& y)  //函数模板
 {  
 	cout <<((x>y)?x:y);  
 }
//函数模板的重载
template < class T>
 void max(T x,T y)  //函数模板
 {  
 	cout << x;  
 }
int main(){
      max((int*)0,(int*)0) ;
      max((int)0,(int)0);
        return 0;
}

函数的特化

使用模板时会遇到一些特殊的类型需要特殊处理,不能直接使用当前的模板函数,所以此时我们就需要对该类型特化出一个模板函数(就是写出一个模板函数专门给该类型使用)

template<class T>
bool Isequal(T& p1, T& p2){
	return p1 == p2;
}

这个模板函数在遇到字符型数据就用不成了,所以特化一个函数模板

template<> // 此处不添加类型模板,直接使用空即可
bool Isequal<char*>(char*& p1, char*& p2){
	return strcmp(p1, p2) == 0;
}

注意:

  1. 使用模板特化时,必须要先有基础的模板函数(就是上面第一个模板函数)
  2. 使用特换模板函数时格式有要求:
    1.template 后直接跟<> 里面不用写类型
    2.函数名<特化类型>(特化类型 参数1, 特化类型 参数2 , …) 在函数名后跟<>其中写要特化的类型
  3. 特化的函数的函数名,参数列表要和原基础的模板函数想相同,避免不必要的错误

C++中的类模板

  • c++中的类模板的写法如下
template <class类塑参数1, class类型参数2, ...>
class 类模板名{
    成员函数和成员变量
};
  • 类模板中的成员函数放到类模板定义外面写时的语法如下:
template <类型参数表>
返回值类型  类模板名<类型参数名列表>::成员函数名(参数表)
{
    ...
}
  • 用类模板定义对象的写法如下:
    有参数:
    类模板名<真实类型参数表> 对象名(构造函数实际参数表);
    无参数:
    类模板名 <真实类型参数表> 对象名;

例子:

#include <iostream>
#include <string>
using namespace std;
template <class T1,class T2>
class Pair
{
public:
    T1 key;  //关键字
    T2 value;  //值
    Pair(T1 k,T2 v):key(k),value(v) { };
    bool operator < (const Pair<T1,T2> & p) const;
};
template<class T1,class T2>
bool Pair<T1,T2>::operator < (const Pair<T1,T2> & p) const
//Pair的成员函数 operator <
{ //"小"的意思就是关键字小
    return key < p.key;
}
int main()
{
    Pair<string,int> student("Tom",19); //实例化出一个类 Pair<string,int>
    cout << student.key << " " << student.value;
    return 0;
}
  • 函数模板作为类模板成员
    类模板中的成员函数还可以是一个函数模板。成员函数模板只有在被调用时才会被实例化。例如下面的程序:
#include <iostream>
using namespace std;
template <class T>
class A
{
public:
    template <class T2>
    void Func(T2 t) { cout << t; }  //成员函数模板
};
int main()
{
    A<int> a;
    a.Func('K');  //成员函数模板Func被实例化
    a.Func("hello");
    return 0;
}

类的特化

前面提到函数模板能被重载,而类模板不可以,我们可以通过特化来实现相似的效果,从而可以透明地获得具有更高效率的代码。
特化也分为了两种,全特化和偏特化:

  • 全特化
    全特化即将所有的模板类型都进行特化,全特化是模板的一个唯一特例,指定的模板实参列表必须和相应的模板参数列表一一对应。
    我们不能用一个非类型值来替换模类型参数。但是如果模板参数具有缺省模板实参,那么用来题还实参就是可选的。
template <class T1, class T2>
class Test
{
}

//全特化
template <>  //此处同函数模板的特化一样不用写内容
class Test<int , char>{
    
}
  • 偏特化
    偏特化感觉像是介于普通模板和全特化之间,只存在部分的类型明确化,而非将模板唯一化。
    是一种部分特化:就是只对函数模板的一部分模板类型进行特化
    再次划重点 函数模板不能被偏特化。
#include <iostream>
using namespace std;

template<typename T1, typename T2>
class A
{
        public:
                void function(T1 value1, T2 value2)
                {
                        cout<<"value1 = "<<value1<<endl;
                        cout<<"value2 = "<<value2<<endl;
                }
};

template<typename T>
class A<T, double>
{ // 部分类型明确化,为偏特化类
        public:
                void function(T value1, double value2)
                {
                        cout<<"Value = "<<value1<<endl;
                        cout<<"doubleValue = "<<value2<<endl;
                }
};

int main()
{
        A<char, double> a;
        a.function('a', 12.3);
        return 0;
}

类的特化优先级

对主版本模板类、全特化类、偏特化类的调用优先级从高到低进行排序是:
全特化类>偏特化类>主版本模板类
这样的优先级顺序对性能也是最好的。

C++类模板中的静态成员

类模板中可以定义静态成员,从该类模板实例化得到的所有类都包含同样的静态成员。

#include <iostream>
using namespace std;
template <class T>
class A
{
private:
	static int count;
public:
	A() { count ++; }
	~A() { count -- ; };
	A( A & ) { count ++ ; }
	static void PrintCount() { cout << count << endl; }
};

template<> int A<int>::count = 0;
template<> int A<double>::count = 0;
int main()
{
	A<int> ia;				//模板类ia
	A<double> da;			//模板类da
	ia.PrintCount();		//只创建一个模板类对象,名为ia
	da.PrintCount();		//只创建一个模板类对象,名为da。
	return 0;
}

不同类型的类模板共享的静态成员变量不是同一块。

类模板下运算符重载的两种用法

1.

template <typename T>
class Complex
{
	friend ostream &operator <<<T>(ostream &out,const Complex &c);
private:
	T m_a;
	T m_b;
public:
	Complex(T a,T b);
	void print();
	
};

friend ostream &operator <<(ostream &out,const Complex &c);

这句的放在运算符<<后是因为该模板类中的成员变量都为T类;
2.

template <typename T>
class Myarray
{
private:
	int m_len;
	T *m_data;
public:
	//Myarray();
	Myarray(int l);
	Myarray(const Myarray &a);
	~Myarray();
	template <typename U>
	friend ostream &operator <<(ostream &out,const Myarray<U> &a);
	T &operator [](int index);
};

friend ostream &operator <<(ostream &out,const Myarray &a);

而此句的类模板中有一个成员变量是int型已确定,因此将放入参数Myarray后。

人形机器人电路板和算法分析 人形机器人电路板与算法深度剖析 电路板领域:人形机器人电子系统分为计算、驱动、感知、能源、通信五大模块。主控板采用高性能SoM(如NVIDIA Jetson AGX Orin),需满足严格电源完整性(PDN)与信号完整性(SI)要求;关节驱动板集成MCU、GaN/SiC功率器件及高精度编码器接口,采用刚柔结合PCB以适应狭小空间。挑战包括热-振可靠性(85°C/10G振动)、高密度互连(3mil线宽)及EMC兼容性。 算法领域:运动控制依赖MPC(模型预测控制)与强化学习(RL),实现实时动态平衡;感知算法 阅读详情

相关推荐

【三维重建】基于多视角图像的三维重建

基于多视角图像的三维重建》

m0_64446860的博客 8762

C++11/14之模板全特化,偏特化

目录模板全特化,偏特化类模板特化类模板全特化a)常规全特化b)特化成员函数而不是模板类模板偏特化(局部特化)a)模板参数数量b)模板参数范围:int , const int(比int小)函数模板特化函数模板全特化函数模板偏特化模板特化版本放置位置建议 模板全特化,偏特化 对特殊的类型(类型模板参数)进行特殊对待,给它写适合它的类型的专用代码。 类模板特化 类模板全特化 a)常规全特化 必须先有...

baidu_41388533的博客 2340

SPSS27 paired t-test 中的Cohen’s D – Effect Size for T-Test

两组数据是相关的且是连续的。

moonlightpeng的博客 910

C++之模板特性详解!(3千字长文)

C++之模板特性详解!(3千字长文)

m0_74376760的博客 643

WSL2不能上网,Failed to connect to github.com port 443问题解决方案

WSL2不能上网: 问题:ping外网无效 例如:ping www.baidu.com失败 解决方案: 在wsl: $sudo vi /etc/wsl.conf wsl.conf: [network] generateResolvConf = false 在PowerShell: $sudo vi /etc/etc/resolv.conf resolv.conf: # This file was automatically generated by WSL. To stop automatic gen

Jason_Chen__的博客 9528

基于激光雷达与视觉融合的四旋翼无人机室内避障方法研究

本文研究了一种基于激光雷达与视觉融合的四旋翼无人机室内避障方法。针对单一传感器在室内环境中的局限性,提出通过激光雷达提供精确几何距离、视觉相机补充语义信息的融合方案。研究内容包括:搭建ROS硬件平台集成单目相机与2D激光雷达;设计基于扩展卡尔曼滤波的传感器融合模型;改进VFH算法结合视觉深度图进行路径规划。实验验证表明,该方法在复杂室内环境下具有较高的鲁棒性、实时性与避障成功率,为解决无GPS信号环境下的无人机自主导航问题提供了有效方案。

huanghm88的专栏 348

c++ 模板的特化

对模板进行特化,在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化与类模板特化(全特化/偏特化).

S5242的博客 4305

Python 实战:手语翻译系统——从视频到文本的智能转换

今天,我们用 Python 构建了一个。

Echo_Wish 344

C++ 模板进阶(模板的特化)

这里我们再次学习模板,这次是进阶模板,要比上次所学的模板更深一些,包括非类型模板参数以及函数模板的特化、类模板的全特化、偏特化等。

冰果滴的博客 2164

9、眼底图像智能分析:糖尿病视网膜病变的自动化识别与分级系统

本博客介绍了一种基于深度学习的糖尿病视网膜病变(DR)自动化识别与分级系统。该系统通过视网膜图像的预处理、数据增强、集成模型的构建与优化,实现了对DR的高效识别与分级。识别系统采用二分类任务,准确率达到97.67%,而分级系统通过四分类策略取得了95.2%的准确率。系统在基层社区和医院中具有广泛的应用前景,为DR的早期筛查和精准诊断提供了有效工具。

pea55的博客 146

直流无刷电机FOC控制算法 理论到实践 —— 实践

关于直流无刷电机FOC控制算法的理论章节,本人已经在前两章进行过详细说明,大家可以自行进行阅读,请务必了解过理论之后再来学习如何具体进行实现。直流无刷电机FOC控制算法 理论到实践 —— 理论(一)直流无刷电机FOC控制算法 理论到实践 —— 理论(二)本章节主要讨论采用MCU微控制器如何具体实现直流无刷电机的FOC控制。

爱出名的狗腿子 1万+

C++ 泛型编程 之模板(template)

C++的 函数模板与类模板

qq_24472227的博客 5825

calibre:将calibre 的layer number 转换为实际的laymer 名称(7)

可以使用与版图数据库配套的(Standard Verification Rule Format,标准验证规则格式),在 Calibre DESIGNrev 中加载图层名称。

u013620135的博客 984

【C++】模板进阶:深入解析模板特化

本章将深入探讨模板的高级应用,重点解析模板特化的概念和实现方法。

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 2522

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【C++】模板进阶(特化)

💬 hello!各位铁子们大家好哇。今日更新了模板的相关内容一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。【优点】模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生增强了代码的灵活性【缺陷】模板会导致代码膨胀问题,也会导致编译时间变长出现模板编译错误时,错误信息非常凌乱,不易定位错误。

qinjh_的博客 3363

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C++初阶:模版相关知识的进阶内容(非类型模板参数、类模板的特化、模板的分离编译)

1.非类型模版参数 2.模板的特化 2.1模版特化引入和概念 2.2函数模版特化 2.3类模板特化 2.3.1全特化 2.3.1偏特化 3.模板分离编译 3.1分离编译概念 3.2模板的分离编译 分析原因

qq_74415153的博客 2080

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++中的模板特化和偏特化

然后进行了偏特化,当 T1 为 int 类型时,新的 Pair 类有一个额外的成员函数 multiply ,用于计算 first 和 second 的乘积。然后针对 bool 类型进行了完全特化,在完全特化的类中可以提供与通用模板不同的实现,比如更高效的存储方式或者特殊的操作方法,以适应 bool 类型的特点。然后对 bool 类型且大小为10的栈进行了完全特化,在特化版本中重新定义了 push 和 pop 等成员函数的具体实现。这种偏特化可以针对特定类型组合进行特殊的处理,以满足不同的需求。

2401_88249494的博客 1266

C++ 中的模板特化和偏特化

当一般的模板定义对于某些特定类型不能满足要求,或者可以提供更高效的实现时,就可以使用模板特化。它不是完全指定模板参数的具体类型,而是对模板参数的某些特性(如指针类型、引用类型、数组类型等)进行特化。(字符串指针)时,上述比较大小的方式就不合适了,因为直接比较指针的值并不能得到字符串内容大小的比较结果。这可以让我们针对指针类型的数组进行特殊的操作,比如更方便地管理指针数组的内存等。还可以对模板参数的其他特性进行偏特化,比如对数组类型。是指针类型时,就会使用这个偏特化的模板类定义,它的数据成员。

2302_81041084的博客 1006

C++模板之模板成员函数不能偏特化

好了,本篇小文就写到这里,总结一下内容,首先实例代码讲解了很多 C++ 书籍都提到,但是没有细说的:“虽然类模板可以偏特化,但是类模板的成员函数不可以偏特化” 这句话的意思,然后又介绍了两种利用函数重载机制实现的变相函数“偏特化”的方法。

红军不怕远征难,万水千山只等闲 1890

C++《模板进阶》

在之前的C++《模板初阶》当中我们初步了解了在C++当中模板的作用,并且了解了模板类和模板函数的定义和实例化时的使用方式,那么接下来在本篇我将进一步的学习模板的相关概念,例如特化,非类型模板参数等,相信通过本篇的学习你将对模板有更深的理解,要求加油吧!

mljy.博客 5027

【C++模板基础知识】模板的特化

**朋友们好,这篇播客我们继续C++的初阶学习,最近我学习了C++中的模板相关知识,模板是泛型编程的基础,十分重要。所以特意整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步!**.........

qq_43727529的博客 699

【C++】模板特化:当泛型代码遇到特殊情况怎么办?

文章摘要: 本文系统探讨了C++模板编程的三大核心内容。首先介绍非类型模板参数的概念与使用,包括C++20前后的支持差异,以及模板静态数组的优势特性;其次详细解析模板特化技术,涵盖函数模板特化和类模板特化(全特化与偏特化),通过日期类比较示例展示实际应用;最后分析模板分离编译问题及解决方案(如将声明定义合并为.hpp文件)。文章还总结了模板编程的优势(代码复用、灵活性)和不足(代码膨胀、错误信息混乱),为开发者提供了全面的模板技术参考。

2401_83431652的博客 1201

【C++】—— 模板进阶

C++模板

yusjushd的博客 2646

C++之,我是如何解决模板特化相关难题的

在C++编程的实际工作中,我遇到了不少与模板特化相关的难题。模板特化作为C++模板机制的重要组成部分,在提供代码灵活性和效率的同时,也带来了一些理解和使用上的挑战。下面我将分享在工作中遇到的典型问题以及解决方法。

wj_rdk的博客 1314

【C++】模板进阶

本篇文章博主会与大家共同学习非类型模板参数、类模板的特化以及模板的分离编译相关内容。

℉f的博客 2044

C++模板特化:定制模板行为

本文介绍了C++模板特化的概念和应用。模板特化包括全特化和偏特化,允许为特定类型提供定制实现。全特化针对所有模板参数提供具体类型实现,而偏特化仅对部分参数特化。通过代码示例展示了如何为指针类型实现特化版本,并讨论了避免特化冲突的原则。模板特化能提高代码性能和灵活性,是模板编程的重要技术。文章还预告了后续将介绍模板元编程内容。

fykam的博客 1183
上一篇: MFC学习:DC,CDC和HDC
下一篇: 武汉理工大学数据结构实验—哈夫曼树压缩图片
Andy in boots
博客等级 码龄7年 73粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值