樣板規格
template宣告會指定一組參數化的類別或函式。
template < template-parameter-list > declaration
備註
樣板參數清單 是逗點分隔的清單範本參數,它可能是型別 (在表單中 類別識別項, 型別名稱識別項,或 範本 < 樣板參數清單 > 類別識別項) 或要使用的範本主體中的非型別參數。 範本參數的語法是下列其中一項:
parameter-declaration
class identifier [ = typename ]
typename identifier [ = typename ]
template < template-parameter-list > class [identifier][= name]
您可以具現化類別樣板得像一般的類別會具現化,但您必須將包含角括號內的樣板引數 (< >)。 如果樣板引數清單中包含類別,這些樣板引數可以是任何型別或型別名稱關鍵字或適當的型別,如果引數型別引數的值。 雖然角括弧和樣板引數可能會需要如果範本參數無法推算出從引數的函式,不必使用特殊語法所需來呼叫函式樣板。
樣板參數清單是樣板函式,可指定下列的程式碼的哪些部分而異所使用的參數清單。 例如:
template< class T, int i > class MyStack...
如此一來,樣板可以接收型別 (class T) 和常數的參數 (int i)。 範本會使用型別T和常數整數i在具現化時。 本文中的MyStack的宣告中,您必須參考T識別項。
樣板宣告本身並不會產生程式碼路徑。 它會指定一系列的類別或函式、 一個或多個它時會產生其他程式碼所參考。
樣板宣告具有全域、 命名空間或類別範圍。 它們不可以宣告為函式中。
下列範例說明宣告、 定義和使用型別參數的類別樣板具現化T和非型別樣板參數 i。
// template_specifications1.cpp
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()
{
}
非型別樣板引數
非型別樣板參數必須是整數、 列舉型別、 指標、 參考或指標成員的型別,並且必須在編譯時期常數。 它們可能會限定為 const 或動態型別。 浮點值不可以當做樣板參數。 雖然允許的這類物件的指標,物件的類別、 結構或等位型別不允許做為非型別樣板參數。 以非型別樣板參數會轉換成指標,就會傳遞陣列。 做為型別參數傳遞的函式會被視為函式指標。 不允許字串常值當作樣板參數。
使用樣板宣告中的型別名稱
型別名稱關鍵字可用的樣板參數清單中。 下列的樣板宣告為同一概念:
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
class Y
{
};
template<class T, T* pT> class X1
{
};
template<class T1, class T2 = T1> class X2
{
};
Y aY;
X1<Y, &aY> x1;
X2<int> x2;
int main()
{
}
樣板當作樣板參數
範本參數本身可能是範本。 這個建構表示引數必須本身是範本,而非類別由範本所組成。 在下列範例中,名稱A範本的樣板參數的參數可省略,因為沒有方法可使用。
// template_specifications3.cpp
#include <stdio.h>
template <class T> struct str1
{
T t;
};
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);
}
Output
5
參考當做範本參數
Visual Studio。NET 2003 引進能夠使用與非型別樣板參數的參考。 這不是允許在舊版中。
// references__supported_as_nontype_template_parameters.cpp
#include <stdio.h>
extern "C" int printf_s(const char*,...);
template <int & ri> struct S
{
S()
{
printf_s("ri is %d\n", ri);
}
~S()
{
printf_s("ri is %d\n", ri);
}
};
int i = 1;
int main()
{
S<i> s;
i = 0;
}
Output
ri is 1
ri is 0
巢狀的範本例項
Visual Studio 到 Visual Studio 2005年之前的版本所需範本參數清單時所宣告的巢狀的樣板的執行個體之間插入的空白字元。 現在允許使用下列語法:
// template_specifications4.cpp
template <typename T>
class A
{
};
template <int n>
class B
{
};
int main()
{
A<B<22>>();
}