C++/C++ 기초

[C++] 템플릿 ( Template ) - 함수 템플릿 / 클래스 템플릿

Song 컴퓨터공학 2023. 5. 5. 16:33

C++ 이 가지는 특징 중 하나로 일반화 프로그래밍(Generic programming) 을 들 수 있습니다. 일반화 프로그래밍이란 쉽게 말하자면 일반적인, 다양한 상황에서도 같은 코드로 적용할 수 있는 것을 말합니다. C++ 에서 일반화 프로그래밍을 할 수 있는 대표적인 기능 중 하나가 바로 템플릿(Template) 입니다.

 

말로는 무슨 소리인지 이해가 잘 안가죠. 간단한 예를 들어보겠습니다.

#include <stdio.h>
#include <stdlib.h>

int max(int a, int b)
{
	if (a > b) return (a);
	else return(b);
}

float max(float a, float b)
{
	if (a > b) return (a);
	else return(b);
}

int main(void)
{
	int a = 2, b = 3;
	float c = 2.0, d = 3.0;
	max(a, b);
	max(c, d);
}

위와 같은 아주 간단한 max 함수, 더 큰 값을 반환하는 함수가 있습니다. 기존의 C++ 언어 문법의 경우 두 함수의 형태가 동일하더라도 매개변수가 int 형과 float 형처럼 데이터 타입이 다르다면 위처럼 동일한 함수를 2번 정의해서 사용해야만 합니다. 이를 함수 오버로딩이라고 배웠죠.

 

만약 char 형에 대해서도 max 함수를 적용하고 싶다면 3개의 함수가 필요합니다. 그런데 셋 다 함수가 아예 같은데, 굳이 3번이나 함수를 정의할 필요가 있을까요? 이 때 템플릿을 사용하면 좀 더 일반적인, int 형도 적용되고 float 형도 적용되고 char 형도 적용되는 generic function 을 만들 수 있습니다. 그를 위한 도구, 템플릿에 대해 알아보도록 하겠습니다.

 

 

템플릿(Template)

 

템플릿이란 매개변수의 타입에 따라 함수나 클래스를 생성하는 메커니즘을 말합니다. 템플릿은 타입이 매개변수에 의해 표현되므로, 매개변수화 타입(Parameterized type) 라고도 불립니다. 템플릿을 사용하면 타입마다 별도의 함수나 클래스를 만들지 않고, 여러 타입에서 동작할 수 있는 단 하나의 함수나 클래스를 작성하는 것이 가능합니다.

 

 

함수 템플릿(Function template)

 

함수 템플릿이란 위의 예시에서도 봤듯 함수의 일반적인 선언을 의미합니다. 함수 템플릿을 사용하면 같은 알고리즘을 기반으로 하면서 서로 다른 타입에서 동작하는 함수를 한 번에 정의할 수 있습니다. 임의의 타입으로 작성된 함수에 특정 타입을 매개변수로 전달하면, C++ 컴파일러는 해당 타입에 맞는 함수를 생성해줍니다.

template <typename 타입이름>
함수 원형
{
   함수 내용
}

위처럼 정의된 타입 이름은 함수의 원형과 본체에서 임의의 타입으로 사용할 수 있습니다. 위처럼 정의한 함수 템플릿을 호출할 때 매개변수로 int 형을 전달하면 함수의 원형과 본체에서 정의된 타입 이름은 모두 int 형으로 바뀝니다.

#include <iostream>
using namespace std;

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

int main(void)
{
	int a = 2, b = 3;
	float c = 2.0, d = 3.1;
	cout << max(a, b) << endl;
	cout << max(c, d);
}

맨 위의 예제 코드를 템플릿으로 사용하면 이렇게 int 형에 대해서도, float 형에 대해서도 모두 적용할 수 있습니다. 워낙 중요하니 하나만 더 예제 코드를 보겠습니다. 값을 바꾸는 Swap() 함수에 대한 템플릿입니다.

 

#include <iostream>
#include <string>
using namespace std;

template <typename T>
void Swap(T& a, T& b);

int main(void)

{
    int c = 2, d = 3;
    cout << "c : " << c << ", d : " << d << endl;
    Swap(c, d);
    cout << "c : " << c << ", d : " << d << endl;
    string e = "Song", f = "Blog";
    cout << "e : " << e << ", f : " << f << endl;
    Swap(e, f);
    cout << "e : " << e << ", f : " << f << endl;
    return 0;
}

template <typename T>
void Swap(T& a, T& b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}

 

클래스 템플릿(Class template)

 

클래스 템플릿이란 클래스의 일반화된 선언을 뜻합니다. 함수 템플릿과 동일한 문법으로 정의됩니다.

template <typename 타입이름>
class 클래스템플릿이름
{
    클래스 멤버 선언
}

함수 템플릿과 똑같으니 클래스 템플릿을 사용하여 다양한 타입의 데이터를 저장할 수 있는 Data 클래스 예시 코드를 보고 마치도록 하겠습니다.

#include <iostream>
using namespace std;

template <typename T>
class Data
{
private:
	T data_;
public:
	Data(T dt);
	T get_data();
};

int main(void)
{
	Data<string> str_data("Song Blog");
	Data<int> int_data(100);

	cout << "str_data : " << str_data.get_data() << endl;
	cout << "int_data : " << int_data.get_data() << endl;
	return 0;
}

template <typename T>
Data<T>::Data(T dt)
{
	data_ = dt;
}

template <typename T>
T Data<T>::get_data()
{
	return data_;
}