본문 바로가기

C++/C++ 문법

[C++] 템플릿 (Template), 함수 템플릿, 클래스 템플릿, 템플릿 특수화

728x90
반응형

템플릿 (Template)

 

템플릿은 말 그대로 특정 기능을 구현하기 위한 코드의 틀을 만들어주는 것이다.

 

즉 일반화된 코드를 작성하여 함수나 클래스에서 다양한 데이터 타입에 대해 재사용할 수 있게 해 준다.

 

 

 

 

 

 

 

함수를 대상으로 하는 템플릿

 

함수 템플릿을 사용하여 함수의 구조는 미리 정의하지만 자료형은 정해지지 않은 상태로 두는 것이 가능하다.

 

예를 들어 아래 코드처럼 작성하였다고 하자.

 

template <typename T>
T Add(T num1, T num2) {
	return num1 + num2;
}

 

위와 같이 작성하면 자료형은 정의하지 않았지만 어떤 자료형이 오더라도 덧셈 연산을 처리할 수 있다.

 

 

위 코드에서 만든 템플릿 함수는 아래 코드처럼 사용이 가능하다.

 

cout << add(5, 7) << endl;
cout << add(5.5, 3.3) << endl;
cout << add<int>(5.5, 2) << endl;
cout << add<double>(1.2, 3.4) << endl;

 

템플릿 함수는 자료형을 명시하지 않으면 자동으로 인자의 자료형으로 대체된다.

 

즉, 첫 번째 줄에서는 T가 int로 두 번째 줄에서는 double로 대체된 것이다.

 

이후 세 번째 네 번째 줄에서는 T의 타입을 명시해 주었는데 이렇게 작성하면 인자의 자료형을 명시한 타입에 맞춰서

형변환을 진행한 후 동작하게 된다.

 

 

 

 

 

 

 

다중 타입 template

 

함수 템플릿은 여러 타입의 매개변수를 가질 수 있다.

 

이럴 때에는 아래 코드처럼 작성할 수 있다.

 

template<typename T1, typename T2>
void typeprint(T1 a, T2 b) {
	cout << a << " " << b << endl;
}

 

 

다중 타입의 template을 사용하는 방법은 아래 코드와 같다.

 

	typeprint('a', 45);
	typeprint<int, double>('a', 45);
	typeprint<int, double>(97, 45.5);

 

 

 

 

 

 

 

 

 

함수 템플릿의 특수화

 

만약 아래 코드처럼 두 데이터의 값을 비교하여 큰 값을 반환하는 함수 템플릿을 작성하였다고 하자.

 

template <typename T>
T Max(T a, T b) {
	return a > b ? a : b;
}

 

그러나 위 코드처럼 작성하였을 때 문제가 있다.

 

바로 a, b 값에 문자열이 들어왔을 때인데 이때 a와 b값은 문자열의 주소값이므로 아무 의미 없는 비교가 돼버린다.

 

따라서 a, b 값에 문자열이 들어왔을 때 사전 순으로 큰 값을 반환하고 싶다면 아래 코드처럼 특수화를 시켜줘야 한다.

 

template <>
const char* Max(const char* a, const char* b) {
	return strcmp(a, b) > 0 ? a : b;
}

 

 

 

 

 

 

 

 

 

클래스 템플릿

 

클래스 템플릿도 함수 템플릿과 동일한 역할을 한다.

 

클래스에 값을 저장하여 동작할 때 클래스의 기능은 동일하지만 값의 자료형만 다를 때 사용할 수 있다.

 

template <typename T>
class Point {
private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0) : xpos(x), ypos(y) { }
};

 

위 코드처럼 클래스 템플릿을 사용하면 Point class를 사용하여 어떤 자료형이든 받을 수 있게 된다.

 

 

템플릿 클래스를 선언하는 방법은 아래 코드와 같다.

 

Point<int> pos1(3, 5);
Point<double> pos2(3.5, 5.5);

 

템플릿 클래스를 선언할 때에는 템플릿 함수와 다르게 자료형의 정보를 생략할 수 없다.

 

 

 

 

 

 

클래스 템플릿의 선언과 정의의 분리

 

클래스 템플릿도 멤버함수를 외부에 정의하는 것이 가능하다.

 

예를 들어 아래와 같은 클래스 템플릿이 있다고 해보자.

 

template <typename T>
class Simpleclass {
public:
	T SimpleFunc(const T& ref);
}

 

 

이 템플릿의 멤버함수 SimpleFunc은 다음과 같이 외부에 정의할 수 있다.

 

template <typename T>
T simpleClass<T>::SimpleFunc(const T& ref) { }

 

 

 

 

 

 

728x90
반응형