C++入门教程:第九篇 - 模板基础

C++基础——模板 模板是一种较为通用的模具,不能单独使用C++除了面向对象编程之外,还有一种是泛型编程,使用的就是模板C++中提供了两种模板:函数模板,类模板。 阅读详情

C++入门教程:第九篇 - 模板基础

模板是C++中用于实现泛型编程的核心特性之一。通过模板,程序员可以编写与类型无关的代码,从而提高代码的重用性和灵活性。模板不仅可以用于函数,也可以用于类。本文将介绍C++中的模板基础,包括函数模板和类模板的定义和使用。

1. 函数模板

函数模板允许你编写可以接受多种数据类型的函数。函数模板的定义和普通函数类似,但使用了模板参数。

1.1 函数模板的基本语法

函数模板的基本语法如下:


cpp

template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

在这个例子中,template <typename T> 声明了一个模板,T 是一个类型参数。max 函数可以接受任何类型的参数,只要这些参数的类型相同。

1.1.1 使用函数模板

你可以像使用普通函数一样使用函数模板。编译器会根据传入的参数类型自动生成相应的函数实例。


cpp

#include <iostream>

using namespace std;

template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    cout << max(10, 20) << endl;          // 使用整数模板
    cout << max(15.5, 10.5) << endl;      // 使用浮点数模板
    cout << max('a', 'b') << endl;        // 使用字符模板

    return 0;
}

cpp

2. 类模板

类模板允许你创建与类型无关的类,从而使类能够处理多种数据类型。类模板的定义类似于函数模板,但它们用于定义类而不是函数。

2.1 类模板的基本语法

类模板的基本语法如下:


cpp

template <typename T>
class Stack {
private:
    vector<T> elements;
public:
    void push(const T& element) {
        elements.push_back(element);
    }

    T pop() {
        if (elements.empty()) {
            throw out_of_range("Stack<>::pop(): empty stack");
        }
        T elem = elements.back();
        elements.pop_back();
        return elem;
    }
};

cpp

在这个例子中,template <typename T> 声明了一个模板,T 是一个类型参数。Stack 类可以处理任何类型的元素。

2.1.1 使用类模板

你可以像使用普通类一样使用类模板。编译器会根据你指定的类型生成相应的类实例。


cpp

#include <iostream>
#include <vector>
#include <stdexcept>

using namespace std;

template <typename T>
class Stack {
private:
    vector<T> elements;
public:
    void push(const T& element) {
        elements.push_back(element);
    }

    T pop() {
        if (elements.empty()) {
            throw out_of_range("Stack<>::pop(): empty stack");
        }
        T elem = elements.back();
        elements.pop_back();
        return elem;
    }
};

int main() {
    Stack<int> intStack;
    intStack.push(1);
    intStack.push(2);
    cout << intStack.pop() << endl;  // 输出2

    Stack<string> stringStack;
    stringStack.push("hello");
    stringStack.push("world");
    cout << stringStack.pop() << endl;  // 输出"world"

    return 0;
}

cpp

3. 模板的特化

模板特化允许你为特定的类型定义不同的模板实现。这包括完全特化和偏特化。

3.1 完全特化

完全特化允许你为某个特定的类型定义一个完全不同的模板实现。


cpp

#include <iostream>
#include <string>

using namespace std;

template <typename T>
class Printer {
public:
    void print(const T& value) {
        cout << value << endl;
    }
};

// 完全特化
template <>
class Printer<string> {
public:
    void print(const string& value) {
        cout << "String: " << value << endl;
    }
};

int main() {
    Printer<int> intPrinter;
    intPrinter.print(123);  // 输出123

    Printer<string> stringPrinter;
    stringPrinter.print("hello");  // 输出String: hello

    return 0;
}

cpp

3.2 偏特化

偏特化允许你为模板参数的一部分定义不同的模板实现。


cpp

#include <iostream>

using namespace std;

template <typename T, typename U>
class Pair {
private:
    T first;
    U second;
public:
    Pair(T f, U s) : first(f), second(s) {}
    void print() {
        cout << first << ", " << second << endl;
    }
};

// 偏特化
template <typename T>
class Pair<T, T> {
private:
    T value1;
    T value2;
public:
    Pair(T v1, T v2) : value1(v1), value2(v2) {}
    void print() {
        cout << "Both values are the same: " << value1 << ", " << value2 << endl;
    }
};

int main() {
    Pair<int, double> p1(1, 2.5);
    p1.print();  // 输出1, 2.5

    Pair<int, int> p2(3, 4);
    p2.print();  // 输出Both values are the same: 3, 4

    return 0;
}

cpp

4. 模板的类型特征(Type Traits)

C++11引入了模板的类型特征,用于在编译时查询类型特性。这对于模板编程非常重要。

4.1 类型特征的基本使用

C++标准库提供了一些类型特征,如std::is_integral、std::is_floating_point等,用于检查类型是否满足某些条件。


cpp

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
void checkType() {
    if (is_integral<T>::value) {
        cout << "T is an integral type" << endl;
    } else if (is_floating_point<T>::value) {
        cout << "T is a floating point type" << endl;
    } else {
        cout << "T is neither an integral nor a floating point type" << endl;
    }
}

int main() {
    checkType<int>();       // 输出T is an integral type
    checkType<double>();    // 输出T is a floating point type
    checkType<string>();    // 输出T is neither an integral nor a floating point type

    return 0;
}

cpp

5. 模板的最佳实践

在编写模板代码时,遵循一些最佳实践可以提高代码的可读性和可维护性。

5.1 适当使用模板

模板是强大的工具,但应当避免过度使用。在可能的情况下,尽量使用标准库中的模板和算法,而不是重新实现相同的功能。

5.2 使用constexpr优化模板

constexpr关键字允许编译器在编译时计算表达式,这可以提高模板代码的性能。


cpp

#include <iostream>

constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

int main() {
    std::cout << "Factorial of 5 is " << factorial(5) << std::endl; // 输出120
    return 0;
}

cpp

5.3 避免模板的编译时间膨胀

模板可能导致编译时间变长,因为每种模板实例化都会生成一个新的代码副本。要注意代码的优化,避免不必要的模板实例化。

6. 总结

本文介绍了C++中的模板基础,包括函数模板、类模板、模板的特化以及类型特征。模板是C++中实现泛型编程的强大工具,可以提高代码的重用性和灵活性。了解模板的基本概念和使用方法可以帮助你编写更加通用和高效的代码。在下一篇教程中,我们将探讨C++中的智能指针,学习如何管理动态内存并提高代码的安全性。

希望这篇文章对你有所帮助。如果你有任何问题或建议,欢迎在评论区留言。我们下篇文章见!

研究:同样的C++模板在多个cpp里出现,编译器是否要重复生成? 2023年就要过去,马上要跨如2024年。祝大家在新的一年,有个好收成。一直以来不是很确定:同样的的模板,在各个cpp分别出现,编译器要实现几份?研究一下。 阅读详情

相关推荐

在VisualStudio添加CPP模板

创建一个模板项目:导出模板:自定义模板内容:重新导入模板: 重启 Visual Studio,您的模板将出现在新建项目的模板列表中。 方法 2:使用代码片段(Code Snippets) 打开代码片段管理器:添加自定义代码片段: 使用代码片段: 在 文件中,输入快捷键 ,然后按 键,注释模板将自动插入。 方法 3:直接修改默认模板 找到默认模板文件: 修改模板:保存并重启 Visual Studio:

PythonWHN的博客 1098

【C++基础】模板

模板就是建立,大大。

qq_43192337的博客 318

C++编程新手到高手:CS42Cpp课程学习之路

本文还有配套的精品资源,点击获取 简介:"CS42Cpp"课程设计为初学者提供了一个系统的C++学习路径,涵盖了从基础知识到高级概念的全面内容。课程分为两个部分:前4周的基础阶段,后16周的深入阶段,逐渐引导学员掌握C++的语法、面向对象编程、高级特性如模板和STL使用。课程利用"CS42Cpp-master"资源包提供实践材料,帮助学员通过实际编码提高编程技能和解决问题的...

weixin_35982453的博客 1602

【C++ 泛型编程 入门篇】C++ 元编程 :模板结构体的的使用教程

C++模板结构体,就是使用了模板的结构体(Struct)。它的设计理念是"编写一次,用于多种数据类型"。换句话说,通过使用模板结构体,你可以创建一个可适应多种类型的代码,而不是为每种可能的类型创建不同的代码。这一点类似于Java和C#中的泛型,但是C++的模板比这两种语言的泛型功能更强大和灵活。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 4250

告别SquareLine!用免费的NXP GUI-Guider为海思3516AV300开发LVGL界面(附完整移植流程)

本文详细介绍了如何利用免费的NXP GUI-Guider工具为海思Hi3516AV300开发LVGL界面,包括环境配置、代码移植和性能优化等全流程实战指南。特别针对二维码组件缺失等常见问题提供解决方案,帮助开发者零成本构建高效嵌入式GUI系统。

weixin_28292761的博客 415

香橙派OPi 6系列选型指南:RK3588与RK3588S开发板深度对比

开发板选型是嵌入式系统设计的关键环节,尤其在边缘计算和AI推理等场景中,芯片的差异直接影响硬件架构。瑞芯微RK3588及其精简版RK3588S是当前高端开发板的核心方案,两者在PCIe通道、显示输出和SATA支持上存在显著区别。理解这些原理,有助于工程师根据项目需求快速匹配产品。香橙派OPi 6系列基于这两款芯片,衍生出OPi 6、OPi 6 Pro与OPi 6 Max三种形态:紧凑型适合嵌入式门禁与AI盒子,Pro版凭借双屏异显和PCIe 3.0满足收银机与视频分析,Max的双2.5G网口和大内存则面向轻

weixin_29185167的博客 222

C++模板详解

C++模板详解

qq_52905520的博客 2万+

基于步科(Kinco HMI 2.5)的组态软件使用

本篇介绍Kinco HMI 2.5的组态软件使用,图标如下 目录   一、新建工程并配置连接 1.1 根据工程选择PLC与HMI型号 1.2 配置PLC连接与选项 二、组态画面编辑 2.1 打开画面窗口 2.2 编辑画面 2.3 组态变量与PLC程序变量连接 三、组态程序下载到HMI 3.1 连接 3.2 编译 3.3 下载 一、新建工程并配置连接 1.1 根据工...

ACanswer的专栏 1万+

【C++】模板(初级)

关于C++中泛型编程——模板的介绍

Brant_zero的博客 750

手把手教你用MATLAB和PSIM搞定Buck电路控制器:从传递函数到运放电路实战

本文详细介绍了如何使用MATLAB和PSIM协同设计Buck电路控制器,从传递函数推导到运放电路实现的完整流程。通过小信号建模、波特图分析和双平台仿真验证,帮助电力电子工程师解决理论到实践的转化难题,提升Buck电路控制器设计的效率和可靠性。

weixin_29271053的博客 267

C语言使用开源库libusb进行USB设备操作

https://libusb.info/libusb is a C library that provides generic access to USB devices. It is intended to be used by developers to facilitate the production of applications that communicate with USB hardware. It is portable: Using a single cross-platform AP

m0_60352504的博客 1553

Cpp入门基础

定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下 ⾯的rand不在冲突了。C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。

2401_86658278的博客 5088

AgentScope Java 入门:Spring AI Alibaba 与 AgentScope 的定位与区别

摘要:Spring AI Alibaba是阿里基于Spring AI开发的本地化AI应用框架,旨在服务Java开发者。它提供模型接入、函数调用、RAG等功能,并与阿里云基础设施深度集成。同时,阿里开源了多智能体框架AgentScope,其Java版(AgentScope-Java)专注于Agentic设计理念。两者将协同发展:Spring AI Alibaba侧重Spring生态集成,AgentScope-Java强化智能体能力。未来计划包括支持AgentScope、升级Admin平台,以及推进Server

SmartSi 1522

【C++】模板进阶---cpp模板的深入探索

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

专注于前后端学习 1234

YOLO11,ultralytics-main源代码目录结构详解

本文详细介绍了YOLO11框架的ultralytics-main源代码目录结构,帮助用户更好地理解和使用YOLO模型。主要目录包括:docker文件夹,包含多种Docker镜像文件,适用于不同硬件环境;docs文件夹,存放YOLO的说明文档;examples文件夹,提供YOLO使用的示例代码;tests文件夹,包含单元测试模块;ultralytics文件夹,为核心代码所在,包含推理逻辑、配置、数据处理等模块。其中,engine文件夹负责训练和推理引擎,models文件夹存放模型架构,nn定义神经网络结构

qq_30279827的博客 1282

有之以为利,无之以为用,在 RAP 开发里的虚实取舍

摘要(149字) SAP RAP框架通过"有"与"无"的哲学平衡实现业务应用价值。其"有"体现在CDS视图、行为定义、服务绑定等具体对象,为系统提供形体;而"无"则表现为保留的扩展空间、未暴露的实现细节和框架托管的生命周期。在采购审批应用中,RAP既通过明确定义的行为模型建立业务语义,又通过验证、动作等机制保持灵活性。这种架构既确保核心功能稳固,又为未来演进留出余地,印证了"有之以为利,无之以为用"的技术智慧

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1302

深入理解 C++ 模板:从基础语法到模板元编程(上)

模板是 C++ 最强大也是最复杂的特性之一,它不仅支持**泛型编程**,还能实现编译时计算和元编程。本文作为模板系列的上篇,将从模板的基础语法开始,结合代码示例,循序渐进地讲解**函数模板**、**类模板**、**模板实参推断**、**模板特化**等核心概念,为深入学习高级模板编程打下坚实基础。

qq_47353388的博客 2552

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

CPP基础学习

CPP基础学习C++ 学习网址C引入C++C++ 重载 引用 友元抽象封装继承多态模板(STL)C++11特性智能指针 C++ 学习网址 CPP 学习 https://www.cplusplus.com/reference/ C++入门教程 面向对象思想 C引入C++ C++struct继承struct C++ 重载 引用 友元 函数重载 抽象 C++ 抽象 封装 C++封装 继承 多态 模板(STL) STL简单例子 Stack_STL C++11特性 智能指针 C++ 智能指针 s

嵌入式与人工智能 1348

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【CPP】CPP的模板(前篇)

模板是分割C和C++的重要的分水线,决定了C语言注定不能取代C++设计模板一般咱称作为泛型编程,泛型编程即通过数据类型编写代码,使得同一段代码能够不断复用,提高了代码的复用性模板一般分为函数模板类模板public:,_size(0),_capa(n){}~Stack()_size = 0;_capa = 0;"

2302_79981653的博客 1598

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

掌握C++模板编程:Cpp-Primer-5th-Exercises第16章实战指南

C++模板编程是C++ Primer第5版第16章的核心内容,也是提升C++编程能力的关键技能。通过Cpp-Primer-5th-Exercises项目中的实战练习,你将系统掌握模板类、函数模板、模板特化等核心概念,轻松应对复杂的泛型编程挑战。 ## 为什么模板编程是C++开发者的必备技能 🚀 模板是C++实现泛型编程的基础,它允许你编写与类型无关的代码,大幅提高代码复用性和灵活性。在标准库

gitblog_00320的博客 935

【C++】模板入门教程

泛型编程的核心思想是编写独立于特定数据类型的代码。这意味着程序员可以定义一套算法或数据结构,而不必为每种可能的数据类型编写特定的代码实现。这种思想的实现极大地提高了代码的复用性和程序的可维护性。想象一下,如果没有泛型编程,对于简单的数据结构如列表、栈或队列,我们可能需要为整型、浮点型、字符串等每一种数据类型编写特定的实现。这不仅会导致大量重复的代码,也会使得维护和更新变得异常困难。泛型编程的一个经典例子是排序算法。不论是整数数组还是浮点数数组,甚至是自定义类型的数组,排序算法的逻辑结构是相同的。

m0_62953935的博客 1194

【CPP】C++模板:初阶到进阶语法与实用编程示例

探索C++模板的深度与广度,《C++模板:初阶到进阶语法与实用编程示例》带您从基础语法起步,逐步深入到高级特性。本博客结合精炼的理论知识和丰富的代码实例,揭示模板编程的精髓,助您提升开发效率,优化代码结构。无论您是初学者还是资深开发者,都能在这里找到提升C++编程技能的宝贵资源。

BinaryWiker的博客 1380

Cpp-Templates-2ed完全指南:从C++11到C++20的终极模板编程教程

C++模板是C++11至C++20标准中最复杂也最强大的特性之一,是构建高性能基础设施库不可或缺的技术。本教程将带你从基础到进阶,全面掌握现代C++模板编程的核心技术与最佳实践。 ## 为什么模板是C++开发者的必备技能 🚀 模板作为C++的元编程基础,允许开发者编写与类型无关的通用代码,在保持类型安全的同时实现代码复用。无论是STL标准库、Boost库,还是现代C++基础设施,模板技术都扮

gitblog_00195的博客 683

C++模板基础知识

为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。因此,与非模板代码不同,模板的头文件通常即包括声明也包括定义。函数模板和类模板成员函数的定义通常放在头文件中。像常规的头文件和源文件分离编译的情况,在模板情况下行不通。如下模板类Blob,在文件中public:public:T getA();U getB();U _b;如果将Blob类中的构造函数及getA()和getB()函数,定义在文件return _a;return _b;那么在。

mo4776的博客 1101

CPP编程语言-模板

函数模板是指:可以用多种不同数据类型的参数进行调用,代表了一个函数家族。模板分为两大类:函数模板和类模板。

qq_45595546的博客 1642

CPP初级:模板的运用!

哇去,这篇文章居然讲透了模板?

duanku111的博客 1315
上一篇: C++入门教程:第八篇 - 文件I/O操作
下一篇: C++入门教程:第十篇 - 智能指针详解
HYP_Coder
博客等级 码龄2年 1678粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值