템플릿 선언은 매개변수화 클래스(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 |
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 Y aY; X1<Y, &aY> x1; int main() |
Template template parameters (템플릿 템플릿 인자)
템플릿 인자는 자체가 템플릿이 될 수 있다. 이 생성자는 템플릿으로부터 생성된 클래스가 아니라 인자 자체가 템플릿이 되는 것을 의미한다. 다음 예는 템플릿 템플릿 인자를 위한 템플릿 인자의 A라는 이름은 생략될 수 있다. 왜냐하면 사용할 방법이 없기 때문이다.
// template_specifications3.cpp template<class T> struct str1 int main() |
[출력 결과]
5
References as Template Parameters (템플릿 인자처럼 참조)
Visual Studio .NET 2003 은 비-타입 템플릿 인자처럼 참조하여 사용하는 기능을 소개했다. 이는 이전 버전에서는 허용되지 않았다.
// references__supported_as_nontype_template_parameters.cpp extern "C" int printf_s(const char*,...); ~S() int i = 1; int main() |
[출력 결과]
ri is 1
ri is 0
Nested Template Instances (네스티드 템플릿 인스턴스) ; nested : 둥지를 튼 것처럼 이중으로 쌓인 모양
Visual Studio 2005보다 앞선 Visual Studio의 버전에서는 네스티드 템플릿 인스턴스가 선언되어질 때 템플릿 인자 목록 사이에 여백(whitespace) 삽입이 필요했다. 다음 문법은 Visual Studio 2005부터 허용되었다.
// template_specifications4.cpp |
흐아.. 이거 생각보다 빡쎄네;; 자연스럽게 써내려가기가 왜 이렇게 시간이 많이 필요하단 말이냐!! ㅜㅜ
다음부터는 좀 늦어지더라도 충분히 내껄로 다 만들고 올려야징
'Programming Languages > C++ Templates' 카테고리의 다른 글
Advantages of Templates [C++] (0) | 2010.08.31 |
---|---|
Templates Overview (0) | 2010.05.10 |
Templates (0) | 2010.05.09 |