c++ template学习总结3

和往常一样,先来看一段代码:

#include <stdexcept> 

template <typename T, int MAXSIZE>
class Stack {
  private:
    T elems[MAXSIZE];        // elements
    int numElems;            // current number of elements
  public:
    Stack();                 // constructor
    void push(T const&);     // push element
    void pop();              // pop element
    T top() const;           // return top element
    bool empty() const {     // return whether the stack is empty
        return numElems == 0;
    }
    bool full() const {      // return whether the stack is full
        return numElems == MAXSIZE;
    }
}; 

// constructor
template <typename T, int MAXSIZE>
Stack<T,MAXSIZE>::Stack ()
  : numElems(0)              // start with no elements
{
    // nothing else to do
} 

template <typename T, int MAXSIZE>
void Stack<T,MAXSIZE>::push (T const& elem)
{
    if (numElems == MAXSIZE) {
        throw std::out_of_range("Stack<>::push(): stack is full");
    }
    elems[numElems] = elem;  // append element
    ++numElems;              // increment number of elements
} 

template<typename T, int MAXSIZE>
void Stack<T,MAXSIZE>::pop ()
{
    if (numElems <= 0) {
        throw std::out_of_range("Stack<>::pop(): empty stack");
    }
    --numElems;              // decrement number of elements
} 

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

接下来编写我们的测试函数:

#include <iostream>
#include <string>
#include <cstdlib>
#include "stack4.hpp" 

int main()
{
    try {
        Stack<int,20>         int20Stack;    // stack of up to 20 ints
        Stack<int,40>         int40Stack;    // stack of up to 40 ints
        Stack<std::string,40> stringStack;   // stack of up to 40 strings 

        // manipulate stack of up to 20 ints
        int20Stack.push(7);
        std::cout << int20Stack.top() << std::endl;
        int20Stack.pop(); 

        // manipulate stack of up to 40 strings
        stringStack.push("hello");
        std::cout << stringStack.top() << std::endl;
        stringStack.pop();
        stringStack.pop();
    }
    catch (std::exception const& ex) {
        std::cerr << "Exception: " << ex.what() << std::endl;
        return EXIT_FAILURE;  // exit program with ERROR status
    }
} 

大家要注意int20Stack和int40Stack是两个不同的类型,他们是不能进行硬是或者显示的转换的。也不能够相互赋值。

你还可以为函数模板定义非型别参数:

template <typename T, int VAL>
T addValue (T const& x)
{
    return x + VAL;
} 

当我们想把【函数】和某种操作作为参数传递的时候,就非常有用,比如在使用STL时,你可能有下面的代码:

std::transform (source.begin(), source.end(),  // start and end of source
                dest.begin(),                  // start of destination
                addValue<int,5>);              // operation

有时候我们为了使得编译器推导的时候简单一些,可以使用:

std::transform (source.begin(), source.end(),  // start and end of source
                dest.begin(),                  // start of destination
                (int(*)(int const&)) addValue<int,5>);  // operation

但是我们要注意,非类型模板参数也有自己的局限,通常来说他们只能是常整数,包括枚举,或者指向外部链接的指针。如果我们用浮点数或者class-type objects作为非类型模板参数是错误的:

template <double VAT>        // ERROR: floating-point values are not
double process (double v)    //        allowed as template parameters
{
    return v * VAT;
} 

template <std::string name>  // ERROR: class-type objects are not
class MyClass {              //        allowed as template parameters
  …
};

由于字串字面常熟是一种采用内部链接的物件,也就是说不通模组中的两个同值的字串字面常数其实是两个不同的东西,所以他们也不能用来作为模板参数:

template <char const* name>
class MyClass {
  …
}; 

MyClass<"hello"> x;   // ERROR: string literal "hello" not allowed

此外全局指针也是不行的:

template <char const* name>
class MyClass {
  …
}; 

char const* s = "hello"; 

MyClass<s> x;         // ERROR: s is pointer to object with internal linkage

但是下面的例子是可以的:

template <char const* name>
class MyClass {
  …
}; 

extern char const s[] = "hello"; 

MyClass<s> x;        // OK

在这个例子中,s是一个外部连接的部件。

时间: 2024-12-30 22:14:02

c++ template学习总结3的相关文章

C++ template学习总结6

对于基本类型来说,并没有一个default模式来讲他们初始化为有意义的值,没有初始化的变量,其指都是未定义的,但是在模板这一块呢?我们可以采用下面的形式: template <typename T> void foo() { T x = T(); // x is zero (or false)ifT is a built-in type } 对于class template我们可以采用下面例子的方式: template <typename T> class MyClass { pr

C++ template 学习归纳总结4

我们在这篇文章来说说typename关键字吧.这个关键字是在c++的标准化过程中引入的,目的在于说明template中的某个表示符号是一个类型,而不是其他的东西,看下面的代码: template <typename T> class MyClass { typename T::SubType * ptr; - }; 第一个typename我就不多说了,大家都知道,我来说一下第二个.他的意思是说T::SubType是class T内部定义的一个类型,从而ptr是一个指向[T:SubType类型]

C++ template 学习归纳2

关于c++中的类模板,常见的形式为: template<typename T> class className{ //... }; 比如笔者在这里举一个例子:   #include <iostream> #include<vector> #include <stdexcept> template<typename T> class stack{ private: std::vector<T> elems; public: void p

jQuery .tmpl(), .template()学习资料小结_jquery

昨晚无意中发现一个有趣的jQuery插件.tmpl(),其文档在这里.官方解释对该插件的说明:将匹配的第一个元素作为模板,render指定的数据,签名如下: .tmpl([data,][options]) 其中参数data的用途很明显:用于render的数据,可以是任意js类型,包括数组和对象.options一般情况下都是选项了,官方指出,此处的options是一个用户自定义的键值对的map,继承自tmplItem数据结构,适用于模板render动作期间. 在这里可以下载到最新的tmpl插件,值

设计模式学习笔记(八)—Template Method模式

<设计模式>一书对Template Method模式是这样描述的: 定义一个操作中算法的骨架,而将一些步骤延迟到子类中.不改变算法的结构而重新定义它的步骤. 我的理解:定义一个抽象类或者说接口,在它的内部定义一些抽象的方法(供TemplateMethod调用的步骤)和一个TemplateMethod方法(非抽象方法),封装了这些抽象方法的接口或抽象类就是骨架.而将它的实现延迟到子类中,也就是用子类实现它.不改变算法的结构而重新定义它的步骤,也就是改写或者实现父类的这些非TemplateMeth

Prototype Template对象 学习_prototype

复制代码 代码如下: var Template = Class.create({ //初始化方法 initialize: function(template, pattern) { this.template = template.toString(); this.pattern = pattern || Template.Pattern; }, //格式化方法,如果从java的角度来说,其实叫format更好 :) evaluate: function(object) {     //检查是否

WPF and Silverlight学习笔记(十八):WPF样式(Style)与模板(Template)

一.WPF样式 类似于Web应用程序中的CSS,在WPF中可以为控件定义统 一的样式(Style).样式属于资源的一种,例如为Button定义统一的背景颜色 和字体: 1: <Window.Resources> 2: <Style 3: TargetType="Button"> 4: <Setter Property="Background" Value="Yellow" /> 5: <Setter Pr

[Java]基本的学习实例

好久没有更新了,偷懒,该打!1.这个是一个基本的文件操作,实现对文件读取.写入一个数字的操作的package trying;import java.io.*; /** * @author gooing */public class FileRw { private File f = new File("d:\\j2\\a.txt"); public int getNum(){ int i = -1; try{ String stri=""; BufferedRead

C++ 学习

  内联函数 inline 内联函数的函数体的限制 (1)   函数体不能含有复杂的结构控制语句,如while和switch,若包括的话,编译器将会将其视为普通函数: (2)   递归不能用于内联函数 (3)   内联函数只适用于小函数 内部函数(static) 外部函数(extern)   结构体(struct)和类(class)的差距 默认的访问权限不一致.        面向对象的三大特点:继承 封装 多态 基于对象   类的定义 访问控制: (1)      用private限定的成员成