C++泛型设计 - 模板规格(译)

C++泛型设计 - 模板规格(译)

 

C++关键字template可以用来声明一批参数化的类(模板类)或函数(模板函数)。

 

一般使用格式如下:

 

template < template-parameter-list > declaration

 

说明

       template-parameter-list是一个以逗号分隔开的模板参数。这些模板参数可能是一些类型(以这种格式:class identifiertypename identifier或是template<template-parameter-list> class identifier)或是一些非类型的参数,它们常用于模板体内,代表着实际使用时指定的类型或是非类型的对象。模板参数的语法如下之一:

 

parameter-declaration

²        class identifier [ = typename ]

²        typename identifier [ = typename ]

²        template < template-parameter-list > class [identifier][= name]

 

你可以像实例化一个普通类一样去实例化一个类模板多次,但你必须以一对尖括号(<>)来包含模板参数。这些模板参数可以是任意类型(template-parameter-list包含class或是typename关键字)或是一个适当类型的值(template-parameter-list包含非类型的参数)。调用一个模板函数没有特定的语法,尽管尖括号和模板参数是必需的(当模板参数不能由参数到函数引出时)。

 

如下所示,template-parameter-list的几个部分都是不同的,这些参数主要用于在模板类中的函数。

 

template< class T, int i > class MyStack...

 

在这个例子中,这个模板可以接爱一个类型(class T)和一个常量参数(int i)。上面这个例子的模板将使用类型T和常量的整数i。在MyStack声明的类体中,你必须引用到这个标识符T

 

一个模板的声明不会产生代码,它仅阐释一个类或函数的组织,当它被其它代码引用时才会产生。

 

模板可以在全局或是名字空间及类域下进行声明,但不能在一个函数内声明。

 

下面这个例子演示了一个类模板以一个类型T及一个非类型模板参数i进行的声明、定义及实例化:

 

实例

 

// template_specifications1.cpp

 

// Template Class Usage 1: The T is Type, and the i is constant value of Integer

template <class T, int i>

class TestClass

{

    public:

        char buffer[i];

        T testFunc(  T* p1 );

};

 

template <class T, int i>

T TestClass<T, i>::testFunc(T* p1)

{

    return *(p1++);

}

 

// To create an instance of TestClass

TestClass<char, 5> ClassInst;

int main()

{}

 

// template_specifications2.cpp

class Y

{};

 

// Template Class Usage 2: The pT is Value of Pointer

template <class T, T* pT>

class X1

{};

 

// Template Class Usage 3: The T2 is optional Default Parameter

template <class T1, class T2 = T1>

class X2

{};

 

// To create those instances of upon classes

Y aY;

X1<Y, &aY> x1;

X2<int> x2;

 

int main()

{}

 

// template_specifications3.cpp

#include <stdio.h>

 

// Template Structure Usage 1Normal

template <class T>

struct str1

{

    T t;

};

 

// Template Structure Usage 2The Type of T can be a template class

template <template<class A> class T>

struct str2

{

    T<int> t;

};

 

int main()

{

    str2<str1> mystr2;

    mystr2.t.t = 5;

    printf_s( “%d/n”, mystr2.t.t );

}

 

/* ---------------------- */

输出

5

// references__supported_as_nontype_template_parameters.cpp

#include <stdio.h>

 

extern “C” int printf( const char*, ... );

 

template <int& ri>

struct S

{

    // constructor method

    S()

    {

printf( “ ri is %d/n”,  ri  );

}

   

    // destructor method

    ~S()

    {

        printf( “ri is %d/n”, ri );

}

};

 

int i = 1;

int main()

{

    S<i> s;

    i = 0;

}

 

/* ---------------------- */

输出

ri is 1

ri is 0

 

非类型的模板参数

 

非类型的模板参数必须是:整数/枚举/指针/引用/指向一个成员类型的指针(例如template_specifications2.cppX1模板类)。正如constvolatile类型一样,在编译时刻它们是不可改变的。另外,float类型的指针不能用作模板参数。尽管一个指向 “类对象/结构/union类型”的指针可用作模板参数,但是它们本身却不可用作模板参数。若传递的是数组名称,就被转化为指针看待。若传递的是函数名称,当然,是被看作为函数指针。字符串是不允许看作为模板参数的。

 

在一个模板声明中使用typename

 

在模板参数列表中,可以使用typename关键字来定义一个参数。例如下面的模板声明是一样的:

 

template <class T1, class T2> class X...

template <typename T1, typename T2> class X...

 

缺省的模板参数

 

类模板可以拥有缺省参数(指定使用赋值操作符赋一个缺省的类型或是一个值)。确记,函数模板不可有缺省参数。

 

/* 类模板缺省参数用法参考简单例子 */

 

template<typename Type>

class allocator

{};

 

template<typename Type, typename Allocator = allocator<Type>>

class stack

{};

 

stack<int> MyStack;

 

模板参数的复用

 

在模板参数列表中,模板参数可以复用。如template_specifications2.cpp例子中的X1模板类的模板参数T在第二个参数中获得到复用。

 

模板的模板参数

 

模板参数也可以进行模板化。这个创立前提条件是,参数本身必须是一个模板,非一个由模板构造好的类。在下面的例子中,模板参数的名称A对于一个模板的模板参数来说,可以省略,因为没有被使用。

 

引用模板参数

Visual Studio .NET 2003引入了一个新特性,可以引用非类型的模板参数。这个方法在以前的版本中是不允许的。

 

—完

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值