非类型模板参数

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

非类型的类模板参数

 

创建类的头文件

#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 == 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) {
        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 <= 0) {
        throw out_of_range("Stack<>::pop(): stack is full");
    }
    --numElems;
}

template<typename T, int MAXSIZE>
T Stack<T, MAXSIZE>::top() const
{
    if(numElems <= 0) {
        throw out_of_range("Stack<>::top(): stack is full");
    }
    return elems[numElems - 1];
}
#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 == 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) {
        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 <= 0) {
        throw out_of_range("Stack<>::pop(): stack is full");
    }
    --numElems;
}

template<typename T, int MAXSIZE>
T Stack<T, MAXSIZE>::top() const
{
    if(numElems <= 0) {
        throw out_of_range("Stack<>::top(): stack is full");
    }
    return elems[numElems - 1];
}

实现代码:

#include<iostream>
#include<vector>
#include<deque>
#include<stdexcept>
#include<string>
#include<cstdlib>
#include "stack4.h"
using namespace std;

int main()
{
    try {
        Stack<int, 20> int20Stack;
        Stack<int, 40> int40Stack;
        Stack<string, 40> stringStack;

        int20Stack.push(7);
        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 0;
}
#include<iostream>
#include<vector>
#include<deque>
#include<stdexcept>
#include<string>
#include<cstdlib>
#include "stack4.h"
using namespace std;

int main()
{
    try {
        Stack<int, 20> int20Stack;
        Stack<int, 40> int40Stack;
        Stack<string, 40> stringStack;

        int20Stack.push(7);
        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 0;
}

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, 5>);

  非类型模板参数的限制

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

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

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

时间: 2024-09-11 06:19:17

非类型模板参数的相关文章

C++非类型模板参数

对 于函数模板与类模板,模板参数并不局限于类型,普通值也可以作为模板参数.在基于类型参数的模板中,你定义了一些具体的细节来加以确定代码,直到代码被调 用时这些细节才被真正的确定.但是在这里,我们面对的是这些细节是值,而不是类型,当要使用基于值的模板时,必须显式地指定这些值,才能够对模板进行实例 化.  本文地址:http://www.cnblogs.com/archimedes/p/cpp-template-type.html,转载请注明源地址. 在上篇文章(C++类模板)中我们介绍了一个sta

C++中非类型模板参数(nontype template parameters) 的使用

非类型模板参数(nontype template parameters), 可以使用整型类型(integral type),指针(pointer) 或者是 引用(reference); 绑定非类型整数形参(nontype integral parameter) 的 实参(argument) 必须是常量表达式(constant expression, constexpr); 不能把普通的局部对象或者动态对象 绑定 指针或引用的非类型形参, 可以使用全局类型进行绑定; 关于类模板(class tem

template-vs2010中非类型模板参数特化问题

问题描述 vs2010中非类型模板参数特化问题 请高人解答: 在vs2010中写一个关于模板的代码,大致如下 通用版本 template< int dimen > float CalcMatrixDet(float p[][]) { } 特化版本 template< > float CalcMatrixDet< 2 >(float p[2][2]) { } 编译出错: 求指点,错在哪里?特化版本应该怎么写? 解决方案 特化了以后就不要加模板了 解决方案二: 你使用模板的

C++之:模板元编程(三) 默认模板参数

一.类模板的默认模板参数原则 1.可以为类模板的类型形参提供默认值,但不能为函数模板的类型形参提供默认值.函数模板和类模板都可以为模板的非类型形参提供默认值. 2.类模板的类型形参默认值形式为: template<class T1, class T2=int> class A{}; 为第二个模板类型形参T2提供int型的默认值. 3.类模板类型形参默认值和函数的默认参数一样,如果有多个类型形参则从第一个形参设定了默认值之后的所有模板形参都要设定默认值,比如 template<class

《C++ Templates中文版》——2.3 模板参数

2.3 模板参数 函数模板有两种类型的参数. 1.模板参数:位于函数模板名称的前面,在一对尖括号内部进行声明: template <typename T> //T是模板参数 2.调用参数:位于函数模板名称之后,在一对圆括号内部进行声明: -max (T const& a, T const& b) //a和b都是调用参数 你可以根据需要声明任意数量的模板参数.然而,在函数模板内部(这一点和类模板有区别),不能指定缺省的模板实参[4].例如,你可以定义一个"两个调用参数的

请问如何修改SAP中 QC20的输出类型模板

问题描述 如题,请教如何修改SAP中QC20的输出类型模板,以前从来没碰到过,网上资料也很少,不知怎么做了 解决方案 解决方案二:你是要修改系统标准的打印报表么?如果是的话,你得找下业务顾问问下,需要在img下将打印相关的参数指定到你自定义的smartform下就OK了.

《深入理解C++11:C++ 11新特性解析与应用》——2.11 模板函数的默认模板参数

2.11 模板函数的默认模板参数 类别:所有人 在C++11中模板和函数一样,可以有默认的参数.这就带来了一定的复杂性.我可以通过代码清单2-26所示的这个简单的模板函数的例子来回顾一下函数模板的定义. 在代码清单2-26中,当编译器解析到函数调用fun(1)的时候,发现fun是一个函数模板.这时候编译器就会根据实参1的类型const int推导实例化出模板函数void TempFun(int),再进行调用.相应的,对于fun("1")来说也是类似的,不过编译器实例化出的模板函数的参数

java-Java用对象作为参数和用简单类型作为参数的效率差别有多大

问题描述 Java用对象作为参数和用简单类型作为参数的效率差别有多大 用简单类型作为参数就是把参数个数和类型写死,改动影响大,如果使用对象传参,就很灵活,但传递对象的效率会差一点,这两种方式该如何取舍? 解决方案 你自己都说了,后者灵活一些,难道你自己还不能取舍性能和灵活性么? 解决方案二: 既然用JAVA了,这点开销还计算在内?

asp生成静态页主要涉及三个方面:模板,参数,fso

fso|静态|模板 asp生成静态页主要涉及三个方面:模板,参数,fso. 1,模板:这个其实就是页面的框架,以下为模板的例子:###############################这就是一个模板###############################<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-t