템플릿 선언은 매개변수화 클래스(parameterized class)나 함수의 집합을 상세히 기술한다.

 template<template-parameter-list> declaration

Remarks

template-parameter-list 는 템플릿 매개변수의 콤마(,)로 구별된 리스트이다. 이들은 classidentifier, typenameidentifier, template < template-parameter-list  > class identifier 등의 형식으로 타입을 나타내거나 템플릿의 본문에서 사용되어질 비(非)-타입 매개변수(non-type parameters)일 것이다.
템플릿 매개변수를 위한 문법의 한 예는 다음과 같다.

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

일반적인 클래스의 인스턴스화(instantiate)보다 원하는대로 더 인스턴스화 할 수 있지만, 꺾은 괄호(< >) 속에 템플릿 인자(template arguments)를 반드시 포함시켜야한다. 이 템플릿 인자는 템플릿 인자의 나열 중 class, typename 키워드, 또는 인자가 비타입 인자의 경우 적당한 타입의 값을 포함한다면, 어떠한 타입으로도 될 수 있다. 이처럼 함수 템플릿을 호출하기 위해 특수한 문법을 요구하지 않음에도 불구하고, 템플릿 매개변수가 인자로부터 함수를 추론할 수 없다면 꺾은 괄호와 템플릿 인자를 요구할 것이다.

template-parameter-list 는 템플릿 함수에 의해 사용되는 매개변수의 목록이며, 뒤따르는 코드 일부분의 특성은 변할 것이다. 예를 들면:

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

이 경우, 템플릿은 타입(class T)과 상수 매개변수(constant parameter : int i)를 받을 수 있다. 템플릿은 인스턴스화에 타입 T와 상수형 정수 i를 사용할 것이다. MyStack 선언의 본문에서 T 식별자를 반드시 참조해야한다.

템플릿 선언 자체는 코드를 생성하지 않는다: 단지 클래스와 함수의 집합체를 서술할 뿐이며, 다른 코드를 참조할 때 하나 혹은 여러 개가 생성될 것이다.

템플릿 선언은 전역(global), 네임스페이스(namespace) 혹은 클래스 범위(class scope)를 가진다. 이들은 함수 외에는 선언될 수 없다.

다음 예는 타입 매개변수 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()
 {
 ...
 }


Non-type template arguments (비-타입 템플릿 인자)

비-타입 템플릿 인자는 반드시 정수형(integral), 열거형(enumeration), 포인터, 참조형(reference) 또는 멤버 타입을 가리키는 포인터여야만 하며, 컴파일 타임에 상수화 되어야한다. 이들은 const나 volatile 타입으로 한정 지어질 수 있다. 부동 소수점 값은 템플릿 인자로 허용되지 않는다. 클래스의 객체나 구조체(struct) 또는 공용체(union)는 템플릿 인자로 허용되지 않지만, 그런 객체를 가리키는 포인터는 허용된다. 배열은 포인터로 변환되어 비-타입 템플릿 인자로 통용된다. 비-타입 인자로 통용되는 함수는 함수 포인터(function pointer)로 다뤄진다. 문자열 상수(String literal)는 템플릿 인자로 허용되지 않는다.

Using typename in a Template Declaration (템플릿 선언에서 typename 사용하기)

typename 키워드는 템플릿 인자 목록에서 사용될 수 있다. 다음 템플릿 선언은 동일하다.

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

Default Arguments for Template Parameters (템플릿 인자의 디폴트 인자)

클래스 템플릿은 = 기호 다음에 디폴트 타입이나 값을 통해 디폴트 인자를 가질 수 있다. 함수 템플릿은 디폴트 인자를 가질 수 없다. 나중에 클래스 템플릿을 위한 디폴트 인자(Default Arguments For Class Templates)에서 자세히 살펴보자.

 template<typename Type> class allocator {};
 template<typename Type, typename Allocator = allocator<Type>> class stack
 {
 };
 stack<int> MyStack;

Reuse of Template Parameters (템플릿 인자 재사용)

템플릿 인자는 템플릿 인자 목록에서 재사용될 수 있다. 다음과 같은 코드는 허용되는 예이다.

  // 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()
 {
 }


Template template parameters (템플릿 템플릿 인자)

템플릿 인자는 자체가 템플릿이 될 수 있다. 이 생성자는 템플릿으로부터 생성된 클래스가 아니라 인자 자체가 템플릿이 되는 것을 의미한다. 다음 예는 템플릿 템플릿 인자를 위한 템플릿 인자의 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);
 }


[출력 결과]

5

References as Template Parameters (템플릿 인자처럼 참조)

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;
 }


[출력 결과]

ri is 1
ri is 0

Nested Template Instances (네스티드 템플릿 인스턴스) ; nested : 둥지를 튼 것처럼 이중으로 쌓인 모양

Visual Studio 2005보다 앞선 Visual Studio의 버전에서는 네스티드 템플릿 인스턴스가 선언되어질 때 템플릿 인자 목록 사이에 여백(whitespace) 삽입이 필요했다. 다음 문법은 Visual Studio 2005부터 허용되었다.

 // template_specifications4.cpp

 template<typename T>
 class A
 {
 };
 template<int n>
 class B
 {
 };

 int main()
 {
    A<B<22>>();
 }




흐아.. 이거 생각보다 빡쎄네;; 자연스럽게 써내려가기가 왜 이렇게 시간이 많이 필요하단 말이냐!! ㅜㅜ
다음부터는 좀 늦어지더라도 충분히 내껄로 다 만들고 올려야징


'Programming Languages > C++ Templates' 카테고리의 다른 글

Advantages of Templates [C++]  (0) 2010.08.31
Templates Overview  (0) 2010.05.10
Templates  (0) 2010.05.09
Posted by 독뽀
,