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引入了一個新特性,可以引用非類型的模板參數。這個方法在以前的版本中是不允許的。

 

—完

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章