템플릿(Template) Lu's…〃 Programing。


템플릿이란?


플릿(template) 한글로 번역하면 형판, 견본 등의 의미가 있다. C++에서도 대충 비슷한 의미로 쓰인다.

 

C++에서의 템플릿은 사용자가 '무엇인지 모를' 타입을 template으로선언하고, 타입을 사용해서 코드를 작성한다. 타입은 종류, 혹은 이상도 가능하다.


템플릿은 함수, 클래스 또는 구조체의 바로 위에 template<typename Ty> 같은 형식으로 적는다. 이 때 typename 대신 class 를 사용해도 동일하다. 뜻은 '무엇인지는 모르는' 타입 Ty가 있으니까 알아둬.

 

 템플릿 타입은 '무엇인지는' 몰라도 '어떤 종류의 타입'인지는 가정하고 코드를 작성한다. 예를 들어, 어떤 수를 더하는 sum이라는 함수를 구현하려고 한다. 함수는 2개의 인자를 받고, 반환형은 왼쪽 인자로 통일하려고 한다(반환형을 통일하는 이유는, 개의 타입 어떤 타입으로 반환될지 모르기 때문이고, 문제가 되는 경우가 있다. 예를 들자면 int + unsignedint 계산 강제로 unsignedint 형변환이 되어 계산된다. int 값이 음수라면 매우 난감한 결과 값을 반환 받게 것이다).

 

말로 하면 어려우니까 코드를 보자. 다음 함수는 함수템플릿 이라고 부른다.

 

template<typename Type1,typename Type2>

Type1 sum(Type1 left, Type2 right)         // Type1 Type2 무엇인지는 모른다.

{                                        // right 강제로 left 타입으로 캐스팅한다.

return left + static_cast<Type1>(right);

}

 

중요한 점은 Type1 Type2 계산이 가능한 타입인지는 고려하지 않는다는 점이다. 만약 Hero Monster라는 클래스를 선언해 놓고, Type1 Type2 타입으로 넣어버리면 전혀 의도하지 않은 결과가 튀어나오거나 최악의 경우에는 컴파일을 실패 것이다.

 

C++에서 템플릿을 사용하면, 템플릿은 컴파일 타임 사용자가 의도한대로 변경되어 코드에 들어간다. , 사용자가 구현한 템플릿은 컴파일 이후에 들어가는 코드의 견본이라는 소리이다.

 


 

 실제로 함수 템플릿의 산출코드는 타입이 명확해지기 때문에, 미리 명확한 타입으로 오버로딩 있다. 이를 함수 템플릿 오버로딩 이라고 한다.

 

 함수 템플릿은 호출될 사용된 인자를 추론하여 인스턴스화 한다. 추론된 인자가 적을수록 선호된다. 주의할 점은, 추론된 인자 수가 동일하여 어떤 인스턴스를 쓸지 모호해지면 컴파일 에러가 발생한다. 이를 막는 방법은 존재하지만 생략한다.

 

위의 예제에서, Hero Monster sum 함수를 지원하고 싶다면 다음 함수를 오버로딩 하면 된다.

 

template<>

auto sum(Monster left, Hero right)        // Monster Hero 명확한 타입이므로

{                                        // 템플릿을 없앴다.

        // TODO...

}

 

또는, 하나를 템플릿으로 둬도 된다.

 

template<typename Ty>

auto sum(Ty left, Hero right)                // Ty + Hero

{

        // TODO...

}

 

template<typename Ty>

auto sum(Monster left, Ty right)                // Monster + Ty

{

        // TODO...

}

 

 

  템플릿은 함수 뿐만 아니라 변수에도 사용 가능하다. 구조체나 클래스에 사용이 가능한데, 연결 구조(linked list)에서 쓰임새가 눈부신다. 리스트의 노드에 들어가는 데이터의 타입이 여러 개라고 프로그래머가 일일이 Ctrl + C, Ctrl + V 필요 없이 컴파일 시점에서 알아서 만들어준다. 템플릿의 이름은 클래스 템플릿이다.

 

 주의할 점은 템플릿 타입이 다른 개의 클래스 템플릿 A, B 전혀 다른 객체라는 점이다. 멤버 변수나 멤버 함수가 매우 비슷하지만 호환되지 않는다. 만약 A, B 번에 관리하고 싶을 경우에는, A, B 클래스 템플릿을 어떤 클래스에 상속 시키면 된다.

 

이런 식으로.

 

template<typename Ty>

class list: public Base{

        // TODO...

};

 

 

class AType;

class BType;

 

list<AType>a;

list<BType>b;

 

Base* base[2]{ &a, &b };

 

 클래스 템플릿은 상속이 가능하며, 클래스 템플릿의 내부에서도 함수 템플릿을 사용할 있다. , 경우 함수 템플릿은 가상함수가 없다.

 



추가로, MSDN에서 템플릿을 설명한 주소를 추가한다. 한글로 잘 번역되어 있으니 도움이 많이 될 것이다.

https://msdn.microsoft.com/ko-KR/library/y097fkab.aspx




덧글

댓글 입력 영역