C++模板

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

1.自定义Stack模板类

#include <vector>
#include <stdexcept>

template <typename T>
class Stack {
  private:
    std::vector<T> elems;     // elements

  public:
    void push(T const&);      // push element
    void pop();               // pop element
    T top() const;            // return top element
    bool empty() const {      // return whether the stack is empty
        return elems.empty();
    }
};

template <typename T>
void Stack<T>::push (T const& elem)
{
    elems.push_back(elem);    // append copy of passed elem
}

template<typename T>
void Stack<T>::pop ()
{
    if (elems.empty()) {
        throw std::out_of_range("Stack<>::pop(): empty stack");
    }
    elems.pop_back();         // remove last element
}

template <typename T>
T Stack<T>::top () const
{
    if (elems.empty()) {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
    return elems.back();      // return copy of last element
}
测试

#include <iostream>
#include <string>
#include <cstdlib>
#include "stack1.hpp"

int main()
{
    try {
        Stack<int>         intStack;       // stack of ints
        Stack<std::string> stringStack;    // stack of strings

        // manipulate int stack
        intStack.push(7);
        std::cout << intStack.top() << std::endl;

        // manipulate string stack
        stringStack.push("hello");
        std::cout << stringStack.top() << std::endl; 
        stringStack.pop();
        stringStack.pop();
    }
    catch (std::exception const& ex) {
        std::cerr << "Exception: " << ex.what() << std::endl;
        return EXIT_FAILURE;  // exit program with ERROR status
    }
}

由于多掉了一次pop所以报错

2.用typdef产生一个特定模板类别名

比如Stack<int>

typedef Stack<int> IntStack;
int main()
{
    IntStack intStack;
    intStack.push(7);
    std::cout << intStack.top() << std::endl;
}
3.模板类的特化

#include <deque>
#include <string>
#include <stdexcept>
#include "stack1.hpp"

template<>
class Stack<std::string> {
  private:
    std::deque<std::string> elems;  // elements

  public:
    void push(std::string const&);  // push element
    void pop();                     // pop element
    std::string top() const;        // return top element
    bool empty() const {            // return whether the stack is empty
        return elems.empty();
    }
};

void Stack<std::string>::push (std::string const& elem)
{
    elems.push_back(elem);    // append copy of passed elem
}

void Stack<std::string>::pop ()
{
    if (elems.empty()) {
        throw std::out_of_range
                ("Stack<std::string>::pop(): empty stack");
    }
    elems.pop_back();         // remove last element
}

std::string Stack<std::string>::top () const
{
    if (elems.empty()) {
        throw std::out_of_range
                ("Stack<std::string>::top(): empty stack");
    }
    return elems.back();      // return copy of last element
}

基于模板类之上,对于特定类型进行重新实现,比如上面就是一个对std:: string的特例实现,内部用deque实现

测试

#include <iostream>
#include <string>
#include <cstdlib>
#include "stack2.hpp"

int main()
{
    try {
        Stack<int>         intStack;       // stack of ints
        Stack<std::string> stringStack;    // stack of strings

        // manipulate int stack
        intStack.push(7);
        std::cout << intStack.top() << std::endl;
        intStack.pop();

        // manipulate string stack
        stringStack.push("hello");
        std::cout << stringStack.top() << std::endl; 
        stringStack.pop();
        stringStack.pop();
    }
    catch (std::exception const& ex) {
        std::cerr << "Exception: " << ex.what() << std::endl;
        return EXIT_FAILURE;  // exit program with ERROR status
    }
}
上面Stack<std::string>使用了特化的类

4.局部特化

若模板类有两个参数,那么确定其中一个参数,另一个未确定的话,则可以说是局部特化
template <typename T1, typename T2>
class MyClass {
	...
};

//偏特化:两个template parameter相同
template <typename T>
class MyClass<T, T> {
	...
};

//偏特化:第二个参数为int
template <typename T>
class MyClass<T, int> {
	...
};
这些概念与c#的泛型是相同的.

5.预设模板

与局部特化概念差不多,但保留了参数,给参数设置了一个默认的类型

#include <vector>
#include <stdexcept>

template <typename T, typename CONT = std::vector<T> >
class Stack {
  private:
    CONT elems;               // elements

  public:
    void push(T const&);      // push element
    void pop();               // pop element
    T top() const;            // return top element
    bool empty() const {      // return whether the stack is empty
        return elems.empty();
    }
};

template <typename T, typename CONT>
void Stack<T,CONT>::push (T const& elem)
{
    elems.push_back(elem);    // append copy of passed elem
}

template <typename T, typename CONT>
void Stack<T,CONT>::pop ()
{
    if (elems.empty()) {
        throw std::out_of_range("Stack<>::pop(): empty stack");
    }
    elems.pop_back();         // remove last element
}

template <typename T, typename CONT>
T Stack<T,CONT>::top () const
{
    if (elems.empty()) {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
    return elems.back();      // return copy of last element
}

示例:这样如果用默认的类型,就可以少指定一个模板类的类型

#include <iostream>
#include <deque>
#include <cstdlib>
#include "stack3.hpp"

int main()
{
    try {
        // stack of ints:
        Stack<int> intStack;

        // stack of doubles which uses a std::deque<> to manage the elements
        Stack<double,std::deque<double> > dblStack;

        // manipulate int stack
        intStack.push(7);
        std::cout << intStack.top() << std::endl;
        intStack.pop();

        // manipulate double stack
        dblStack.push(42.42);
        std::cout << dblStack.top() << std::endl; 
        dblStack.pop();
        dblStack.pop();
    }
    catch (std::exception const& ex) {
        std::cerr << "Exception: " << ex.what() << std::endl;
        return EXIT_FAILURE;  // exit program with ERROR status
    }
}

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

相关推荐

【UV打印机】PrintExp打印软件教程(二)-主界面介绍

PrintExp软件主界面如下图所示PrintExp软件的主界面主要包括主菜单区,工具栏区,界面显示区,状态栏。以下是上述部分的介绍。

Print World的专栏 6300

C++ template 模板的模板参数(5.4节)

有时,让模板参数本身成为模板是很有用的,我们将继续以stack类模板作为例子,来说明模板的模板参数的用途。在Stack的例子中,如果要使用一个和缺省值不同的内部容器,程序员必须两次指定元素类型。也就是说,为了指定内部容器的类型,你需要同时传递容器的类型和它所含元素的类型。如下: Stack<int, std::vector<int>> vStack; //使用vector的int栈 然而,借助于模板的模板参数,你可以只指定容器的类型而不需要指定所含元素的类型,就可以声明这个Stack

chenyijun的专栏 1118

智能车竞赛蚂蚁搬家组:NXP-MicroPython与STC单片机协同搬运策略解析

本文深入解析智能车竞赛蚂蚁搬家组中NXP-MicroPython与STC单片机的协同搬运策略。通过硬件选型、通信架构设计、效率优化及实战经验分享,展示了如何利用NXP-MicroPython的实时控制与STC单片机的感知导航优势,实现高效多智能体协同作业,为参赛团队提供实用技术参考。

motor的博客 1080

C++ 模板详解(一)

C++模板   模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。   模板是一种对类型进行参数化的工具;   通常有两种形式:函数模板和类模板;   函数模板针对仅参数类型不同的函数;   类模板针对仅数据成员和成员函数类型不同的类。   使用模板的目的就是能够让程序员编写与类型无关的代码。...

weixin_33699914的博客 1634

UE5 C++教程(一、基本结构)

虚幻API由三块组成,分别是Runtime,Developer utilitiew,functionality for the Editor,大多数游戏性编程只使用运行时模块,最常见的三个是Corn、CornUObject和Engine。

skycol的博客 1万+

LVGL的基础知识总结

另外,还有自定义字库的使用,具体可参考开发手册。

qq_28576837的博客 7390

实现Stack容器类

#include &lt;vector&gt; #include &lt;iostream&gt; template&lt;typename T&gt; struct Stack { void push(T const&amp; elem); void pop(); T top() const; bool empty() const { return elems.empty();...

xunye的博客 370

避坑指南:STM32CubeMX配置SDIO4bit模式时为什么卡在HAL_SD_ConfigWideBusOperation?

本文深入分析了使用STM32CubeMX配置SDIO 4位模式时,程序在HAL_SD_ConfigWideBusOperation函数处卡死的常见问题。文章从硬件连接、CubeMX配置、初始化序列及HAL库底层实现等多个维度剖析根源,并提供了从初始化流程优化到增强代码鲁棒性等实战解决方案,帮助开发者彻底解决这一棘手难题。

pca5navigator的博客 825

数据结构学习笔记之栈(含数制转换,括号匹配,表达式求值转逆波兰)

#include &lt;iostream&gt; #include &lt;cstring&gt; #include &lt;ctype.h&gt; #include &lt;string&gt; #include &lt;cstring&gt; #include &lt;malloc.h&gt;//gcc6.3可不加 #include &lt;stdlib.h&gt; #include &a

dzydzy7的博客 545

最全中文停用词表(可直接复制)

最全的停用此表整理 词表名 词表文件 中文停用词表 cn_stopwords.txt 哈工大停用词表 hit_stopwords.txt 百度停用词表 baidu_stopwords.txt 机器智能实验室停用词库 scu_stopwords.txt 以上停用词表链接:https://github.com/goto456/stopwords 以下是我常用的1893个停用词,可直接复制 ! " # $ % & ' ( ) * + , - -- . .. ... ....

dilifish的博客 12万+

手把手教你用HiNet实现图像隐藏:可逆神经网络实战指南(附代码)

本文提供了一份基于HiNet框架实现图像隐藏的实战指南。通过详细解析可逆神经网络原理,手把手指导环境搭建、模型构建、损失函数设计及训练流程,并附有完整代码。该方法利用单个可逆网络统一隐藏与恢复过程,结合小波变换提升隐蔽性,为信息隐藏应用提供了高效解决方案。

rgv234567的博客 433

我的C++实践(1):Stack的实现

   (1)基本的Stack:以std::deque为内部容器。方法有入栈、出栈、返回栈顶元、判断栈空。//stack1.h:栈的基本实现#ifndef __STACK1_H__#define __STACK1_H__#include #include templateclass Stack{private: std::deque elems; //包含元素的容

Jack Zhou的专栏 3439

linux arm64 Debian12移植操作手册

2023年6月10号Debian官方出了debian12 arm64版本的。如果需要完全适配这个系统的话,需要linux6.10版本。应客户的需求,需要在Debian11升级为Debian12版本。

qq_45147279的博客 2169

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

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

专注于前后端学习 1235

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

jre9下载 jdk9

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

黑马C++笔记——模板(CPP)

C++模板的常见操作

感觉画质不如...原神的博客 988

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++ 在.h文件中声明,在.cpp文件中定义 模板函数和模板类

C++ 需要模板函数的定义和声明要放在一起,这样才能根据调用需要选择编译具体的实例。如果我们需要多种实例,每个实例要编译一次,就需要编译多次。在模板函数实现妥当以后,当我们在其它文件中使用某些模板函数的时候,基本所有实例都会被重新编译。如果每次编译时间过长,势必会停滞我们的思维,拖长开发进度。所以在模板函数实现妥当以后,我们希望他只编译一次,在非当前模块被修改时,他也不会被重新编译。这篇博客就是介绍

Expressing Youself Using Code 1万+

数学建模模型总结

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

【C++】简单理解CPP模板

了解模板的概念,函数模板与类模板,以及它们的基础用法

DEXTERFUTIAN的博客 702

c++ 模板的实现位置讨论(.h cpp)

本文,仅针对模板函数的写的位置做讨论(记录)。          首先,c++的模板是要有调用,才会被编译的。  因为本身函数要被编译成具体的参数,函数名,返回值类型的一条函数记录(个人理解),记录在函数表中, 而模板本身就是一个泛型, 只有被调用的时候才会产生一个具体的函数记录。  比如        template Class TestC { Public:        

mincheat的专栏 1024

【CPP】CPP的模板(前篇)

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

2302_79981653的博客 1600

【CPP杂货篇】C++模板(超详细)

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时才被参数化,根据实参类型产生函数的特定类型版本。定义格式:class 类模板名// 类内成员定义模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生增强了代码的灵活性模板会导致代码膨胀问题,也会导致编译时间变长出现模板编译错误时,错误信息非常凌乱,不易定位错误。

2302_78684687的博客 861

RedPanda-CPP项目模板使用技巧:快速创建专业C/C++工程

RedPanda-CPP是一款基于Qt开发的轻量级C/C++集成开发环境(IDE),它提供了丰富的项目模板功能,帮助开发者快速搭建专业的C/C++工程。本文将详细介绍如何充分利用RedPanda-CPP的项目模板,提升开发效率,让你轻松创建规范的C/C++项目。 ## 为什么使用项目模板? 项目模板是RedPanda-CPP的核心功能之一,它能够: - 提供标准化的项目结构,确保代码组织一致性

gitblog_01423的博客 868

CPP模板编程

语法形式如下:多个参数用逗号分隔。template <typename t1,typename t2,...... > 返回值类型 函数名(参数列表){//函数体template <class t1,class t2,......> 返回值类型 函数名(参数列表){//函数体template关键字表示这是一个模板定义。typename T声明了一个类型参数T,表示函数可以接受任何类型作为此参数。模板定义中 <> 里的内容即模板参数列表,不能为空t1 : t2;

qq_59805046的博客 1137

c++详解模板泛型编程,详解类模板的实现为什么不能放在cpp文件

泛型编程是一种编程范式,它允许程序员编写与类型无关的代码,从而在编译期确定具体的类型。我们通过模板编写一个函数可以让编译器,自动生成对应类型的实现,这大大减少了重复代码的出现,还提高了代码的可维护性和可扩展性,很重要的一点是模板有特性。

z3363的博客 1066

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

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

BinaryWiker的博客 1380

cpp之模板

这里只针对模板对于一些数组或者类作为参数的情况,函数模板无法正确运行了;我们可以运用以前学过的运算符重载,不过那会显得非常麻烦,所以这里就有了函数模板的重载,即提供一个具体化的模板。如果是全局函数在类内实现友元函数那么直接实现就可以了,但是如果是在类外实现友元函数,我们需要提前让编译器知道全局函数的存在。,这和之前的默认函数参数规则是一样的,不过要注意的是如果我们全部使用了默认参数也要在调用时写上空列表即。不仅要告知编译器模板参数的存在,还要告知其不为普通函数的类外实现,而是函数模板的类外实现。

2303_80883523的博客 1509

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

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

gitblog_00195的博客 683
上一篇: 队列另一种实现(链表)
下一篇: Apollo Rule Reverse
hongjunbj
博客等级 码龄21年 5粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值