c++模板(代码片段)

lvmf lvmf     2022-12-14     576

关键词:

模板Template)——支持将类型作为参数的程序设计。允许定义类,函数或类型别名时将类型或参数作为参数

  指C++程序设计语言中的函数模板与类模板,是一种参数化类型机制,大体对应于java和C#中的泛型,但也有一些功能上的显著差异(C++模板支持后两者没有明确对应的模板模板参数和模板非类型参数,但不支持Java的通配符以及C#的泛型类型约束)。模板是C++的泛型编程中不可缺少的一部分。

多重继承与运算符重载。C++的标准函数库提供的许多有用的函数大多结合了模板的概念,如STL以及iostream。

 

模板的声明与定义

  模板定义以关键字template开始,后接模板形参表(template parameter list),模板形参表是用尖括号<>括住的一个或者多个模板形参的列表,形参之间以逗号分隔。模板形参可以是表示类型的类型形参(type parameter),也可以是表示常量表达式的非类型形参(non-type parameter),非类型形参跟在类型说明符之后声明。类型形参跟在关键字class或typename之后声明。模板形参可以给出默认值(default arguments for template parameters)。

模板的非类型形参

模板的非类型形参(template non-type parameter)允许为下述形式:

  • 整型或枚举型
  • 到对象的指针或函数指针
  • 到对象的引用或函数引用
  • 成员指针

 模板的非类型参数被声明为数组或函数的,将被转换为指针或函数指针。例如:

1 template<int a[4]> struct A  ;
2  template<int f(int)> struct B  ;
3  int i;
4  int g(int)  return 0;
5  A<&i> x;
6  B<&g> y;

 

模板的非类型形参允许用const或volatile限定(而模板的类型形参是不允许cv限定的)。模板的非类型形参是不允许声明为浮点型、class类型、void型。

模板的模板参数

类模板的模板参数允许是另外一个类模板,这称为模板的模板参数(template template parameter),也译作“模板参数模板”。函数模板不允许有模板的模板参数。例如:

1 template<template <class T> class X> class A  ; //类模板A的第二个参数是另外一个类模板X
2 template<class T> class B  ;
3 A<B> a; //模板A的实际使用。其中的B是模板的模板实参(template template argument)

 

模板参数的默认值

模板形参可以给出默认值(default arguments for template parameters)。如果一个模板参数给出了默认值,那么模板形参列表中在其后声明的模板参数都应该给出默认值。例如:

template<class T = char, class U, class V = int> class X  ; //编译出错,或者给出U的默认值,或者不给出T的默认值

 

一个模板的各次声明给出的模板参数的默认值可以累积其效果。例如:

template<class T, class U = int> class A;
template<class T = float, class U> class A;
template<class T, class U> class A 
  public:
     T x;
     U y;
;
A<> a; //a.x is float, and the type of a.y is int

 

但是如果交换本示例第一行与第二行的次序,将编译报错。因为如果第一个模板参数T有了默认值,此时编译器必须已经知道其后的第二个模板参数U的默认值。

在同一个作用域(scope)中,不能对同一个模板的同一个参数多次声明其默认值。例如:

template<class T = char> class X;
template<class T = char> class X  ;//编译报错。如果在本行中不给出模板参数T的默认值将编译通过

 

模板参数的作用域为从其声明之处至该模板的定义结束之处。因此可以使用一个模板参数作为其后声明的其他模板参数的一部分或默认值。例如:

template<class T = char> class X;
template<class T = char> class X  ;//编译报错。如果在本行中不给出模板参数T的默认值将编译通过

 

变量模板

变量模板(variable template)是C++14引入的新的一个种类的模板。可用于在名字空间作用域声明一个变量。例如:

1 template<class T>
2 constexpr T pi = T(3.1415926535897932385);  // variable template
3 template<class T>
4 T circular_area(T r) // function template
5 
6    return pi<T> * r * r; // pi<T> is a variable template instantiation
7 

 

可以在类作用域声明一个静态数据成员:

template<class T>
constexpr T pi = T(3.1415926535897932385);  // variable template
template<class T>
T circular_area(T r) // function template

   return pi<T> * r * r; // pi<T> is a variable template instantiation

 

类的静态数据成员模板,也可以用类模板的非模板数据成员来实现:

struct limits 
   template<typename T>
   static const T min; // declaration of a static data member template
;
template<typename T> const T limits::min =  ; // definition of a static data member template
template<class T> class X 
    static T s; // declaration of a non-template static data member of a class template
;
template<class T> T X<T>::s = 0; // definition of a non-template data member of a class template

 

变量模板不能用作模板的模板参数(template template arguments)。

模板的使用

使用模板时,可以在模板名字后面显式给出用尖括号括住的模板实参列表(template argument list)。对模板函数或类的模板成员函数,也可不显式给出模板实参,而是由编译器根据函数调用的上下文推导出模板实参,这称为模板参数推导

如果模板参数使用其默认值,则在模板实参列表中可以忽略它。如果所有的模板参数都使用了默认值,模板实参列表为空,但仍然必须写出成对的尖括号。例如:

1 template<class T = int> class X  ;
2 X<> a; //编译通过
3 X b;   //编译报错

 

对于作为类型的模板实参,不允许是局部类型(local type)、无链接性的类型(type with no linkage)、无名类型(unnamed type)或包括了这三种情形的复合类型。但C++11以及允许本地类型作为模板实参。

 

c++进阶模板(代码片段)

目录类模板 模板的特化函数模板特化:类模板特化:全特化:偏特化/半特化模板分离编译=====>>> 分析解决方案:按需实例化 模板小结类模板 //类模板template<classT>classStackpublic: Stack(int... 查看详情

c++函数模板(代码片段)

所谓模板,就是模板,但与我们所熟知的模子不同,模板用于生成不同的东西(函数或者类)。在C++中有函数模板和类模板。今天我们来探讨一下函数模板。场景:我们需要一个函数来做加法运算又或者我们需要自己实现print函... 查看详情

c++初识模板(代码片段)

模板1.泛型编程2.函数模板(1)概念(2)函数模板的格式(3)函数模板的原理(4)函数模板的实例化隐式实例化显式实例化(5)模板参数的匹配原则3.类模板(1)类模板的定义格式... 查看详情

c++提高教程模板-类模板(代码片段)

#include<iostream>#include<string>usingnamespacestd;template<classNameType,classAgeType>classPersonpublic: Person(NameTypename,AgeTypeage) this->m_Name=name; this->m_A 查看详情

c++模板(代码片段)

...好优化并且易读易拓展自解释的代码,并且配套文档。C++模板的代码,文档,比赛源码都已放在github上代码规范,图论,字符串,多项式单独成篇通用技巧递归程序防止爆栈在Windows上,通常的方法是在编译选项中加入-Wl,--stack=10... 查看详情

c++模板进阶(代码片段)

模板进阶目标非类型模板参数模板的特化概念模板的编译函数模板的特化类模板化全特化偏特化--重点模板分离编译什么是分离编译模板分离所带来的优点普通.h文件实例化模板所造成问题解决方法首先介绍一下.hpp与.h区别解决... 查看详情

c++模板进阶(代码片段)

模板进阶目标非类型模板参数模板的特化概念模板的编译函数模板的特化类模板化全特化偏特化--重点模板分离编译什么是分离编译模板分离所带来的优点普通.h文件实例化模板所造成问题解决方法首先介绍一下.hpp与.h区别解决... 查看详情

c++模板进阶(代码片段)

文章目录前言一、非类型模板参数1.引出2.概念3.注意(1)非类型模板参数必须是整型(2)非类型模板参数是常量(3)缺省模板参数二、模板的特化1.概念2.函数模板的特化3.类模板的特化4.偏特化三、模板... 查看详情

c++——初识模板(代码片段)

文章目录泛型编程函数模板函数模板概念函数模板格式函数模板的原理函数模板的实例化模板参数的匹配原则类模板类模板的定义格式类模板的实例化泛型编程泛型编程:编写与类型无关的通用代码,是代码复用的一种... 查看详情

c++模板进阶(代码片段)

C++模板进阶#C++模板初阶1.非类型模板参数template<classT,size_tN>classArrayprivate: Tarr[N];;模板参数分为类型参数和非类型参数,如上述所述代码就是非类型模板参数非类型参数:出现在模板的参数类表中,更... 查看详情

c++模板初阶(代码片段)

文章目录泛型编程函数模板函数模板概念函数模板格式函数模板的原理函数模板的实例化模板参数的匹配原则类模板类模板的定义格式类模板的实例化泛型编程如何实现一个通用的交换函数呢?//交换int类型的数据voidSwap(int&a... 查看详情

c++模板(进阶)(代码片段)

模板非类型模板参数模板的特化概念函数模板特化类模板特化全特化偏特化模板的分离编译模板的分离编译解决方法模板的总结非类型模板参数模板参数分类分为类型形参与非类型形参类型形参:出现在模板参数列表中,... 查看详情

c++模板(代码片段)

文章目录前言一、函数模板1.1函数模板的概念1.2函数模板类型1.3函数模板的原理1.4函数模板的实例化1.4.1隐士实例化1.4.2显式实例化1.5模板参数的匹配原则二、类模板2.1类模板的定义格式2.2类模板的实例化总结前言本节将为大家... 查看详情

c++模板(代码片段)

文章目录C++模板函数模板函数模板的实例化隐式实例化:让编译器根据实参推演模板参数的实际类型显示实例化:在函数名后用<>来指定实际类型模板参数的匹配原则总结:类模板模板的分离编译问题C+&#... 查看详情

c++模板进阶(代码片段)

非类型模板参数模板参数”缺省“模板的特化显示具体化实例化与具体化注意重载解析针对类模板的特化全特化偏特化模板分离编译非类型模板参数模板参数类型模板参数:用typename/class定义的参数类型名称非类型模板参数&#... 查看详情

c++初阶---模板入门(代码片段)

模板入门@[TOC](模板入门)泛型编程函数模板概念模板函数实例化隐式实例化显式实例化模板函数匹配类模板泛型编程有如下代码:voidSwap(int&left,int&right) inttemp=left; left=right; right=temp;当我们想调用其他类型的... 查看详情

c++之模板进阶(代码片段)

模板进阶文章目录模板进阶非类型模板参数非类型模板参数缺省值模板的特化概念函数模板的特化类模板的特化全特化偏特化模板分离编译什么是分离编译模板总结优点缺点没了解过模板的读者,先学习模板初阶:C+&#... 查看详情

c++模板(函数模板/类模板)(代码片段)

文章目录一.泛型编程二.函数模板(1).函数模板的实例化(2).非类型模板参数三.类模板(1).类模板的成员函数(2).非类型模板参数四.模板的特化(1).函数模板特化(2).类模板特化五.模板不支持分离编译一.泛型编程在引入泛型编程之前,... 查看详情