프로그래밍 언어/C & C++ 정리

템플릿의 특수화

게임 개발 2023. 5. 18. 22:08
  • 암시적 구체화

암시적 구체화를 사용하는 이유는

말 그대로 암시적인 제한성 때문인데,

 

사용하기를 원하는 데이터형을 나타내는 하나 또는 그 이상의 객체를 선언하기 때문이다.

 

 ArrayTP < int, 100 > stuff;                              // 암시적 구체화

 

컴파일러는 객체가 요구될 때까지 그 클래스의 암시적 구체화를 생성하지 않는다.

 

 ArrayTP < double, 30 >  *pt;                              // 포인터, 아직 객체가 필요 없다.

pt = new ArrayTP <double, 30>;                         // 이제 객체가 요구된다.

 

두 번째 구문은 컴파일러에게 하나의 클래스 정의와,

그 정의에 따라 생성되는 하나의 객체를 생성하라고 지시한다.

 

  • 명시적 구체화

키워드 template을 사용하여 클래스를 선언하고, 사용하려는 데이터형을 나타냈을 때,

컴파일러는 명시적 구체화 (explicit instantiation)를 생성한다.

 

그 선언은 템플릿의 정의와 동일한 이름 공간 안에 있어야한다.

예를 들면, 다음과 같은 선언은

 

                        template class ArrayTP <string,100>;

                                                // ArrayTP <string, 100> 클래스를 생성한다.

 

 ArrayTP <string,100>이 클래스라고 선언한다.

이 경우에는 컴파일러는,

그 클래스의 객체가 아직 생성되거나 언급되지 않았더라도,

메서드 정의들을 포함하여 그 클래스 정의를 생성한다.

-> 여기서 클래스의 정의란 클래스 형태를 말한다.

 

암시적 구체화와 마찬가지로,

이 포괄적인 템플릿은 특수화를 생성하기 위한 설계도로도 사용이 된다.

 

 

  • 명시적 특수화

명시적 특수화 (explicit specialization)는 포괄적인 템플릿 대신에, 

사용하려는 특정한 데이터형 (또는 데이터형들)을 위한 정의이다.

 

즉, 특정 데이터형을 위한 함수 템플릿이라는 것이다.

 

때로는 템플릿이 특정형에 맞게 구체화될 때

조금 다르게 행동하도록 수정해야 하는 경우가 있다.

 

이러한 경우에 우리는 명시적 특수화를 생성할 수 있다.

예를 들어, 정렬된(sorted) 배열을 나타내는 클래스를

위한 템플릿을 정의했다고 가정하자.

 

이때 항목들이 배열에 추가될 때 행렬이 이루어진다.

 

또한 그 템플릿이 값들을 비교하기 위해

> 연산자를 사용하는 특수한 경우를 예시로 들었을 때를 연상시키면

명시적 특수화의 특징을 이해하기 쉬울 것이다.

 

명시적이지 않은 포괄적인 템플릿과 명시적인 템플릿의 형태가 중복하게 된다면

포괄적인 데이터형 대신에 

구제척인 하나의 데이터형에 맞게 정의된 템플릿 형식을 취한다.

 

즉, 컴파일러는 템플릿 요청을

포괄적인 템플릿 정의 대신에 

특수화된 정의를 사용할 것이다.

 

  • 부분적인 특수화

C++는 부분적인 특수화 (partial specialization)도 허용한다.

부분적인 특수화는 템플릿의 포괄성을 일부 제한한다.

 

예를 들어, 부분적인 특수화는 데이터형 매개변수들중의

어느 하나에 구체적인 데이터형을 제공할 수 있다.

 

// 포괄적인 템플릿

                        template <class T1, class T2> class Pair { . . . };

// T2를 int로 설정한, 부분적인 특수화

                        template <class T1, class Pair<T1, int> { . . . };

 

여러 가지 중에서 하나를 선택해야 한다면,

컴파일러는 가장 특수화된 템플릿을 사용한다.

 

포인터들을 위한 특별한 버전을 제공함으로써,

기존의 템플릿을 부분적으로 특수화시킬 수 있다.

 

부분적인 특수화는 개인적인 견해로는,

템플릿의 제한적인 성향을 두드러지게 나타내는

어떠한 자료형의 수용을 금지시키기 위해서도 유용할 것 같다.

 

  • 멤버 템플릿

템플릿은 구조체, 클래스, 템플릿 클래스의 멤버가 될 수 있다.

템플릿 클래스 내에 템플릿 함수를 멤버를 내포할 수 있다.

 

하지만 템플릿 클래스 내에 템플릿 함수를 사용할 경우

템플릿 구현이 아직 새로운 진행 과정이기 때문에,

독자가 사용하는 컴파일러가 이러한 형식을 허용하지 않을 수도 있다.

 

어떠한 컴파일러들은 템플릿 멤버를 전혀 받아들이지 못한다.

 

템플릿 멤버들은 클래스 바깥에 정의를 두는 것은 허용하지 않는다.

사용하는 컴파일러가 이 문제들에 대해 매우 호의적일 경우에는,

 

템플릿 메서드를 템플릿 바깥에 정의하는 경우가 될 것이다.

 

  • 매개변수 템플릿

 

int n과 같은 데이터형이 아닌 매개변수를 가질 수 있다는 사실을 숙지하고 있다면,

또한 템플릿 그 자체가 템플릿인 매개변수를 가질 수 있다.

템플릿 매개변수는, 표준 템플릿 라이브러리를 구현하기 위해 사용된,

최근에 추가된 템플릿 기능이다.

 

 

  • 템플릿 클래스와 프렌드 함수

템플릿 클래스 선언도 프렌드를 가질 수 있다.

템플릿의 프렌드를 다음 3가지로 분류할 수 있다.

 

  1. 템플릿이 아닌 프렌드
  2. 바운드 템플릿 프렌드. 클래스가 구체화될 때 데이터형에 의해 프렌드의 데이터형이 결정된다.
  3. 언바운드 템플릿 프렌드. 프렌드의 모든 특수화가 그 클래스의 각 특수화에 대해 프렌드들이다.

템플릿 클래스에 대한 템플릿이 아닌 프렌드 함수 <- 나중에 정리하기

 

 

 

 

 

 

 

 

++

 

만약 내가 다음에 또 c++로 구조를 짜서 포토폴리오를 하게 된다면,

몬스터 템플릿을 따로 만들어서

공통된 몬스터를 템플릿으로 만들어보는 것이 좋다.