c++模板全面解析

c++模板全面解析

模板作为c++的一个重要功能,自己对它的使用非常的少,所以决定写一篇文档出来加深自己的记忆。本文是根据c++ primer plus第六版中关于模板的部分写成。

一、引言

在我们实际的使用中有时候难免要对不同的数据类型进行相同的操作,如果我们对每一种数据类型都实现相同的操作,无疑是在重复造轮子,实际意义并不大。c++中的模板为我们解决这个问题提供了一个很好的方法。

模板提供参数化类型,即能够将类型名作为参数传递给接收方来建立类或函数。像c++中的STL就是通过模板来实现的。

二、类模板

1、定义

template<typename T>
class Stack {
private:
    enum {MAX = 10};
    T items[MAX];
    int top;
public:

    bool push(const Type& item);
    //在类声明中定义了方法(内敛定义),则可以省略模板前缀和类限定符
    bool pop(Type & item) {
        //ToDo
    }
};

bool Stack<Type>::push(const Type& item) {
    //ToDo
}

另一种定义
类模板不仅可以是参数类型,也可以是非参数类型。但是模板代码不能修改参数的值,例如n++或&n等表达式。另外实例化模板时,用作表达式参数的值必须是常量表达式。

template <class T, int n>
class ArrayTP {

};


默认类型模板参数
不提供第二个参数时第二个参数默认为int类型

```c++
template <class T, class T = int>
class ArrayTP {

};

2、使用

模板的具体实现被称为实例化具体化。不能将模板成员函数放在独立的实现文件中。由于模板不是函数他们不能单独编译。模板必须与特定的模板实例化请求一起使用。为此,最简单的方法是将所有模板的信息放在同一个头文件中,并在要使用这些模板的文件中包含该头文件

模板多文件编译问题

仅在程序中包含模板并不能生成模板类,而必须请求实例化。为此需要声明一个类型为模板类的对象,方法是使用所需的具体类型替换泛型名。例如,下面的代码创建两个栈,一个用于存储int,一个用于存储string对象

Stack<int> kernels;//基础类型int
Stack<string> colonels;//对象类型string

模板的多功能性

递归使用模板
即模板中嵌套模板
常用的vector<vector>定义一个二位的数组

三、模板的具体化

模板的具体化分为三类。分别是隐式实例化,显示实例化,显示具体化

1、隐式实例化

声明一个对象或多个对象,指出所需的类型,而编译器使用通过模板提供的处方生成具体的类定义。

编译器在需要对象之前不会生成类的隐式实例化

ArrayTP<double, 30> * pt;//一个指针,并没有生成对象
pt = new ArrayTP<double, 30>;//现在才生成对象

2、显示实例化

当使用template关键字并指出所需类型来声明类型时,编译器将生成类声明的显示实例化。声明必须位于模板定义所在的名称空间中。

template class ArrayTP<string, 100>

在这种情况下,虽然没有创建或提及类对象,编译器也将生成类声明。和隐式实例化一样,也将根据通用模板来生成具体化。

3、显示具体化

显示具体化是特定类型的定义。有时候可能需要在为特殊类型实例画、化时,对模板进行修改,使其行为不同。在这种情况下,可以创建显示具体化。

在这种情况下可以提供一个显示模板具体化,这将采用为具体类型定义的模板,而不是为泛型定义的模板。当具体化模板和通用模板都与实例化请求匹配时,编译器将采用具体化的版本。

具体化类模板的定义如下:

template <> class Classname<specialialized-type-name> { ... };

4、部分具体化

c++还允许部分具体化,即部分限制模板的通用性。例如部分具体化可以给类型参数之一制定具体的类型:

//general template
template <class T1, class T2> class Pair { ... };
//specialization with T2 set to int
template <class T1> class Pait <T1, int> { ... };
//specialization with T2 and T1 set to int 
template <> class Pair <int, int> { ... };//转换成了显示具体化

如果有多个模板可供选择优先选择具体化程度最高的模板。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STL是指标准模板库(Standard Template Library),它是C++语言的一部分,提供了一系列的模板类和函数,用于支持通用的数据结构和算法。STL的目标是提供高效、可重用和可扩展的组件,以便开发人员能够更轻松地编写高质量的代码。STL包含了许多常见的数据结构,如vector、list、set、map等,以及各种算法,比如排序、查找、遍历等。通过使用STL,开发人员可以更加高效地处理各种数据结构和算法的问题,提高代码的开发效率和质量。 在STL中,我们可以使用各种容器来存储和管理数据。例如,我们可以使用std::map来创建一个键值对的映射,其中每个键都有一个与之相关联的值。下面是一个示例代码,展示了如何创建和使用一个std::map对象: std::map<std::string, int> disMap() { std::map<std::string, int> tempMap{ {"C语言教程",10},{"STL教程",20} }; return tempMap; } std::map<std::string, int> newMap(disMap()); 在这个示例中,disMap()函数创建了一个临时的std::map对象,并初始了其中的一些键值对。然后,使用移动构造函数将这个临时对象移动到了一个新的std::map对象newMap中。最终,我们可以通过newMap对象来访问和操作这些键值对。 综上所述,STL是C++中的标准模板库,提供了一系列的模板类和函数,用于支持通用的数据结构和算法。STL的使用可以提高代码的开发效率和质量,并且通过各种容器和算法,可以方便地处理各种数据结构和算法的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ STL详解超全总结(快速入门STL)](https://blog.csdn.net/qq_50285142/article/details/114026148)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【C++实验】阅读STL源码并分析](https://blog.csdn.net/qq_35760825/article/details/125311509)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值