对于函数模板与类模板,模板参数并不局限于类型,普通值也可以作为模板参数。在基于类型参数的模板中,你定义了一些具体的细节来加以确定代码,直到代码被调用时这些细节才被真正的确定。但是在这里,我们面对的是这些细节是值,而不是类型,当要使用基于值的模板时,必须显式地指定这些值,才能够对模板进行实例化。

本文地址:http://www.cnblogs.com/archimedes/p/cpp-template-type.html,转载请注明源地址。

在上篇文章(C++类模板)中我们介绍了一个stack类模板作为例子,下面将看一个新版本的stack模板,来叙述本文将要介绍的特性:

非类型的类模板参数

创建类的头文件

#include<stdexcept>
#include<iostream>
using namespace std; template<typename T, int MAXSIZE>
class Stack{
private:
T elems[MAXSIZE];
int numElems;
public:
Stack();
void push(T const&);
void pop();
T top() const;
bool empty() const {
return numElems == ;
}
bool full() const {
return numElems == MAXSIZE;
}
}; template<typename T, int MAXSIZE>
Stack<T, MAXSIZE>::Stack():numElems() {} template<typename T, int MAXSIZE>
void Stack<T, MAXSIZE>::push(T const& elem)
{
if(numElems == MAXSIZE) {
throw out_of_range("Stack<>::push(): stack is full");
}
elems[numElems] = elem;
++numElems;
} template<typename T, int MAXSIZE>
void Stack<T, MAXSIZE>::pop()
{
if(numElems <= ) {
throw out_of_range("Stack<>::pop(): stack is full");
}
--numElems;
} template<typename T, int MAXSIZE>
T Stack<T, MAXSIZE>::top() const
{
if(numElems <= ) {
throw out_of_range("Stack<>::top(): stack is full");
}
return elems[numElems - ];
}

stack4.h

实现代码:

#include<iostream>
#include<vector>
#include<deque>
#include<stdexcept>
#include<string>
#include<cstdlib>
#include "stack4.h"
using namespace std; int main()
{
try {
Stack<int, > int20Stack;
Stack<int, > int40Stack;
Stack<string, > stringStack; int20Stack.push();
cout<<int20Stack.top()<<endl;
int20Stack.pop(); stringStack.push("hello");
cout<<stringStack.top()<<endl;
stringStack.pop();
stringStack.pop();
}
catch(exception const& ex) {
cerr<<"Exception: "<<ex.what()<<endl;
//return EXIT_FAILURE;
} cin.get();
return ;
}

main

MAXSIZE是新加入的第二个模板参数,类型为int,它指定了数组最多可包含的栈元素的个数
同样,我们可以为模板参数指定缺省值:

template<typename T = int, int MAXSIZE = 100>
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, >);

非类型模板参数的限制

非类型模板参数是有限制的,通常而言,它们可以是常整数(包括枚举值)或者指向外部链接对象的指针。

浮点数和类对象是不允许作为非类型模板参数的:

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"初始化,是一个外部链接对象

C++非类型模板参数的更多相关文章

  1. C++ Template之非类型模板参数

    非类型模板参数是通过基本变量类型引入,例如int,在使用时必须显式自定值,不能通过推断. 非类型模板参数的限制:不能是浮点数(在vc6.0上测试可以为浮点型),对象以及指向内部链接对象的指针. #in ...

  2. C++标准库函数 end 的实现原理(非类型模板参数)

    在刚开始学习<C++ Primer>的时候遇到了 end 函数,感觉很神奇,但又很迷惑:为什么能获得数组的尾后指针呢?编译器也不会在内存中申请一块空间放数组元素的个数啊!最近再一次遇到了 ...

  3. c++11-17 模板核心知识(三)—— 非类型模板参数 Nontype Template Parameters

    类模板的非类型模板参数 函数模板的非类型模板参数 限制 使用auto推断非类型模板参数 模板参数不一定非得是类型,它们还可以是普通的数值.我们仍然使用前面文章的Stack的例子. 类模板的非类型模板参 ...

  4. 《深入实践C++模板编程》之三——模板参数类型详解

    非类型模板参数 和 模板型模板参数 整数以及枚举类型:指向对象或者函数的指针:对对象或函数的引用:指向对象成员的指针.统称为非类型模板参数. 模板型模板参数,是指模板参数还可以是一个模板.   1.整 ...

  5. 读书笔记 effective c++ Item 44 将与模板参数无关的代码抽离出来

    1. 使用模板可能导致代码膨胀 使用模板是节省时间和避免代码重用的很好的方法.你不需要手动输入20个相同的类名,每个类有15个成员函数,相反,你只需要输入一个类模板,然后让编译器来为你实例化20个特定 ...

  6. C++模板参数类型(转载)

    实际上有三种类型模板参数:类型模板参数.无类型模板参数和模板模板参数(以模板作为模板的参数). .类型模板参数 类型模板参数是我们使用模板的主要目的.我们可以定义多个类型模板参数: template& ...

  7. c++11-17 模板核心知识(十二)—— 模板的模板参数 Template Template Parameters

    概念 举例 模板的模板参数的参数匹配 Template Template Argument Matching 解决办法一 解决办法二 概念 一个模板的参数是模板类型. 举例 在c++11-17 模板核 ...

  8. c++特性:指向类成员的指针和非类型类模板参数和函数指针返回值 参数推导机制和关联型别

    一.c++允许定义指向类成员的指针,包括类函数成员指针和类数据成员指针 格式如下: class A { public: void func(){printf("This is a funct ...

  9. C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则

    背景:    最近在学习C++STL,出于偶然,在C++Reference上看到了vector下的emplace_back函数,不想由此引发了一系列的“探索”,于是就有了现在这篇博文. 前言:     ...

随机推荐

  1. JavaScript 32位整型无符号操作

    在 JavaScript 中,所有整数字变量默认都是有符号整数,这意味着什么呢? 有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数. 数值范围从 -2^ ...

  2. 从头学Qt Quick(1) --体验快速构建动态效果界面

    自2005年Qt4发布以来,Qt已经为成千上万的应用程序提供了框架服务,现在Qt已经基本上支持所有的开发平台了,这里面既包含了桌面.嵌入式领域,也包括了Android.IOS.WP等移动操作平台,甚至 ...

  3. AssetBundle系列——打包前进行平台检测

    在生成AssetBundle的时候,如果目标平台和当前平台不一致,Unity3D会自动将当前平台转换为目标平台. 如果项目中资源量比较大,这个转换过程是相当漫长的,并且不能够强行中止. 所以最好在Bu ...

  4. Hibernate基础映射

    在说Hibernate映射前,我们先来了解下对象关系映射 ORM.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现.这样开发人员就可以把对数据库的操作转化为对这些对象的操作.我们 ...

  5. 疯狂的ASP.NET系列-第一篇:啥是ASP.NET

    最近想学下ASP.NET,于是在网店上看到一本书叫做ASP.NET高级程序设计,老婆在旁边问了句:“这个不是DSP(数字信号处理,大学读的电子,所以这个比较熟),是ASP啊,什么是ASP啊?”.我想了 ...

  6. 斐波那契堆(二)之 C++的实现

    概要 上一章介绍了斐波那契堆的基本概念,并通过C语言实现了斐波那契堆.本章是斐波那契堆的C++实现. 目录1. 斐波那契堆的介绍2. 斐波那契堆的基本操作3. 斐波那契堆的C++实现(完整源码)4.  ...

  7. 【转载】C/C++ 函数指针 总结

    转载自:http://blog.csdn.net/shihui512/article/details/9787125 什么是函数指针函数指针的声明函数指针的赋值函数指针的使用将函数作为其他函数的参数在 ...

  8. HMM 自学教程(三)隐藏模式

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...

  9. iOS-上拉刷新,下拉加载-----------详解

    一.使用的第三方库 1.AFNetworking       ----> 网络请求 2. MJRefresh           ----> 刷新 3. MBProgressHUD  -- ...

  10. 第一次接触终极事务处理——Hekaton

    在这篇文章里,我想给出如何与终极事务处理(Extreme Transaction Processing (XTP) )的第一次接触,即大家熟知的Hakaton.如果你想对XTP有个很好的概况认识,我推 ...