14. 템플릿

  1. 템플릿
  2. 함수 템플릿
  3. 클래스 템플릿



1. 템플릿

템플릿은 함수나 클래스와 같은 객체를 생성할 때, 이러한 함수나 클래스를 찍어내는 주형 또는 틀과 같은 역할을 한다.

예를 들어, int 타입 데이터를 저장할 수 있는 동적 배열을 구현한다고 가정하자. 이후에 float 타입 데이터를 저장할 동적 배열이 필요해 진다면, 이전에 int 동적 배열의 코드를 일부만 수정해서 하나의 클래스를 다시 정의해야 한다.

이러한 비효율적인 과정을 줄이기 위해, C++ 에서 객체가 선언될 때 자료형을 지정하여 입력받고 자료형을 객체 정의 내부에 넣어 선언과 동시에 틀에서 찍어내듯이 해당 함수 또는 클래스를 정의해 주는 것이 바로 템플릿이다.



template <typename T>
class Vector{
    T* data;
    int capacity;
    int count;
}
...

//객체 선언

Vector<float> fvec;


위의 코드에서, 클래스 Vector는 템플릿 인자로 T를 받으며, T는 반드시 어떠한 자료형을 받아야 한다.

이후 해당 자료형의 객체를 선언할 때, <> 를 클래스(또는 함수)의 이름 뒤에 붙여 자료형을 지정하면, 이 때 해당 자료형이 T에 들어가는 클래스(또는 함수)가 정의된다.

그 이전에는 정의되지 않으므로, 만약 해당 클래스를 파일 분할하여 구현할 경우, 템플릿은 반드시 헤더 파일에 구현해야 한다.

헤더가 아닌 cpp 파일에 구현될 경우, 헤더만을 include 하는 다른 파일에서는 객체 선언 시 해당 함수 또는 클래스의 존재만 정의되고 내부 구현은 정의되지 않으므로, 이후에 링크 과정에서 오류가 발생한다.




2. 함수 템플릿



#pragma once

template<typename T>
T Add(T _a, T _b) {
	return _a + _b;
}


함수 템플릿은 위와 같이 구현이 가능하다. 위의 예시는 입력받은 두 변수를 함수 호출 시 변수 타입을 지정하여 호출한 후, 해당 자료형에 해당하는 합연산을 수행하는 함수이다.

이를 함수 오버로딩으로 해결하려 하면 같은 함수가 자료형의 개수만큼 필요하므로 템플릿으로 효율적인 구현이 가능하다.




3. 클래스 템플릿



#pragma once

template<typename T>
class Node {
private:
	T data;
	Node* prevNode;
	Node* nextNode;
};

template<typename T>
class List {
private:
	Node<T>* headNode;
	int count;

public:
	//...

};


위의 예시는 T 라는 자료형을 저장하는 노드와, 그 노드로 이루어진 리스트 구현의 일부이다.

이처럼 클래스의 구현에도 템플릿으로 자료형을 유동적으로 받아 올 수 있다.

이후 이 리스트를 호출 할 경우 아래와 같이 호출할 수 있다.



#include "cpp14.h"


int main() {

	List<int> iList;	// int 데이터를 저장하는 리스트 객체 선언

	return 0;
}