C++ 非类型的模板参数
对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数。
文章目录
- 非类型的类模板参数
- 非类型的函数模板参数
- 非类型模板参数的限制
- 总结
非类型的类模板参数
#include <stdexcept>template <typename T, int MAXSIZE>
class Stack{private:int elems[MAXSIZE]; //包含元素数组int numElems; //元素的当前个数
public:Stack(); //构造函数void push(T const&); //压入元素void pop(); //弹出元素T top() const; //返回栈顶元素bool empty() const { //返回栈是否为空rerurn numElems == 0;}bool full() const { //返回栈是否已满return numElems == MAXSIZE;}
};//构造函数
template <typename T, int MAXSIZE>
Stack<T, MAXSIZE>::Stack() : numElems(0)
{}//压入元素
template <typename T, int MAXSIZE>
void Stack<T, MAXSIZE>::push(T const& elem)
{if (numElems == MAXSIZE){trow std::out_of_range("Stack<>::push(): Stack is full!");}elems[numElems] = elem; //附加元素++numElems; //增加元素的个数
}//弹出元素
template <typename T, int MAXSIZE>
void Stack<T, MAXSIZE>::pop()
{if (numElems <= 0){trow std::out_of_range("Stack<>::push(): empty Stack!");}--numElems; //减少元素的个数
}//返回栈顶元素
template <typename T, int MAXSIZE>
T Stack<T, MAXSIZE>::top() const
{if (numElems <= 0){trow std::out_of_range("Stack<>::push(): empty Stack!");}return elems[numElems-1]; //返回最后一个元素
}
为了使用上述模板,必须同时指定元素的类型和个数(即栈的最大元素容量)。
Stack<int, 20> int20Stack;
Stack<int, 40> int40Stack;
Stack<std::string, 40> stringStack;
当然,上面的模板同样可以为模板参数设置缺省值:
template <typename T = int, int MAXSIZE = 99>
class Stack{......
}
非类型的函数模板参数
你也可以为函数模板定义非类型参数。例如:
template<typename T, int VAL>
T addValue(T const& x)
{return x + VAL;
}
如果需要把函数或者操作用作参数的话,这类函数就相当有用。借助于标准模板库(STL),可以传递这个函数模板的实例化给集中的每一个元素,让他们都增加一个整数值:
std::transform(source.begin(), source.end(), //源集合的起点和终点 dest.begin(), //目标集合的起点 (int(*)(int const&))addValue<int, 5>; //操作(或者函数)
上面的调用,最后一个实参实例化的函数模板addValue(),它上int元素加5。源集合source中的每一个元素都会加5将结果存在目标集合中。下面是一个使用std::transform()函数的例子:
#include "Stack.hpp"
#include <iostream>
#include <vector>
#include <algorithm>template<typename T, int VAL>
T addValue(T const& x)
{return x + VAL;
}int main()
{std::vector<int> source;source.push_back(1);source.push_back(2);source.push_back(3);std::vector<int> dest;dest.resize(source.size()); //这一句不能少!!!std::transform(source.begin(), source.end(), dest.begin(), (int(*)(int const&))addValue<int, 5>);for (int i = 0; i < dest.size(); i++){std::cout << dest[i] << " ";}system("pause");return 0;
}
非类型模板参数的限制
非类型模板参数是有限制的,通常是常整数(包括枚举值)或者指向外部链接对象的指针。
浮点数和类对象是不允许作为非类型模板参数:
template<double VAT>
double process(double v) //error:浮点数不能作为非类型模板参数
{return V * VAT;
}template<string name> //error:类对象不能作为非类型模板参数
class MyClass {...
};
由于字符串文字是内部链接对象(因为两个具有相同名称但出于不同模块的字符串,是两个不同的对象),所以不能使用它们作为模板实参。
不能使用全局指针作为模板参数:
template<char const* name>
class MyClass {...
};char const s[] = "hello";
MyClass<s> x; //s是一个指向内部链接对象的指针
但是我们可以这样来使用:
template<char const* name>
class MyClass {...
};extern char const s[] = "hello";
MyClass<s> x; //OK
全局字符数组s由"hello"初始化,是一个外部链接对象。
总结
模板参数不但可以是类型,也可以是值。
非类型模板参数,不能使用浮点数、class类的对象和内部链接对象(例如string)作为实参。
详情参考:《C++Templates》
C++ 非类型的模板参数相关推荐
- c++模板 --- 类模板、自定义类型当做模板参数
生成一个类模板 类中用到了未知类型叫做类模板 用 template 修饰的类,这个类就是一个模板类 多用在数据结构中,忽略类型的问题 只要被 template 修饰,就是一个模板类,有没有用未知类型都 ...
- C++ 泛型编程(二):非类型模板参数,模板特化,模板的分离编译
目录 非类型模板参数 函数模板的特化 类模板的特化 全特化 偏特化 部分参数特化 参数修饰特化 模板分离编译 问题分析 解决方法 非类型模板参数 模板的参数分为两种,一种是非类型参数,一种是类型参数. ...
- 非类型模板参数(参考《C++ Templates 英文版第二版》)
非类型模板参数(参考<C++ Templates 英文版第二版>) Chapter 3 3.1 非类型类模板参数 与前几章的简单例子不同,你也可以通过std::array实例化一个固定大小 ...
- C++基础——非类型模板参数
非类型类模板参数 非类型函数模板参数 非类型模板参数的限制 非类型模板参看,顾名思义,模板参数不限定于类型,普通值也可作为模板参数.在基于类型的模板中,模板实例化时所依赖的是某一类型的模板参数,你定义 ...
- 模板的模板参数与非类型模板参数
模板参数-实现容器适配器 我们在学习栈和队列时,通过数组或链表实现,这里C++提供一种实现方式:容器适配器. 用vector或者list为容器,适配出一个stack或queue,具体是如何实现? 基本 ...
- 浅谈非类型模板参数、模板的特化
非类型模板参数 1.模板参数分类类型形参与非类型形参. 2.类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称.类型参数也可以给缺省值 3.非类型形参,就是用一个常 ...
- C++知识点60——非类型模板参数
模板参数不仅可以使类型,也可以是值.可以用特定的类型名(比如int)而非typename或者class表示非类型模板参数.当模板被实例化时,非类型模板参数会被一个值而不是类型替代.非类型模板参数 一. ...
- binarytreenode”使用 类 模板 需要 模板 参数列表_c++1117 模板核心知识(一)—— 函数模板...
目录 定义函数模板 使用函数模板 两阶段翻译 Two-Phase Translation 模板的编译和链接问题 多模板参数 引入额外模板参数作为返回值类型 让编译器自己找出返回值类型 将返回值声明为两 ...
- C++非类型模板参数
对于函数模板与类模板,模板参数并不局限于类型,普通值也可以作为模板参数.在基于类型参数的模板中,你定义了一些具体的细节来加以确定代码,直到代码被调用时这些细节才被真正的确定.但是在这里,我们面对的是这 ...
- java两个函数名字相同_为什么C不允许两个具有相同名称的函数/类模板,只有非类型模板参数(整数类型)的类型不同?...
我尝试这个时编译器会出错 . 我试过VC和g . 这同样适用于函数模板和类模板(但对于函数模板,只有在实例化函数模板时才会出现编译器错误;当编译器遇到第二个类定义时,会立即出现类模板的编译器错误) . ...
最新文章
- javascript publish/subscribe or observer pattern
- 【技术贴】虚拟机 VMware win7 win8网卡驱动下载 解决虚拟机不识别网卡没有本地连接...
- 面试题编程题06-python 输入一个字符串,反转输出
- P3374 【模板】树状数组 1
- 解决无法安装cnpm,cnpm卡顿问题
- 响应式 媒体查询 盒模型
- 设计模式-Builder和Factory模式区别
- Mysql 无法插入中文,中文乱码解决
- 30天自制操作系统 pdf_30天自制操作系统:第三天:系统引导完成
- 配置hadoop 使用fair scheduler调度器
- php+windows+信号,php 处理信号简单演示
- 安装spinningup填坑ERROR: Could not build wheels for mpi4py which use PEP 517
- B. Shifting Sort- Codeforces Round #744 (Div. 3)
- HTML5期末大作业:个人网页设计——薛之谦6页(代码质量好) 学生DW网页设计作业源码 web课程设计网页规划与设计
- 2022最新性能测试面试题(带答案)
- JAVA基础学习(二)
- 如何删除PDF中指定的一页或几页?
- 笔记本电脑安装 OMV 关闭屏幕自动休眠的问题
- IMPLEMENTATION MANUAL SWAN Cycle III version 41.31
- (附源码)springboot 个人健康管理 毕业设计 202031