본문 바로가기
SWE/C++ OOP

[c++] template(템플릿)이란? | 함수 템플릿, 알고리즘 추상화

by S나라라2 2019. 9. 27.
반응형
  • 템플릿이란?

함수나 클래스가 개별적으로 다시 작성하지 않고도 각기 다른 수많은 자료형에서 동작할 수 있게 한다.

템플릿의 종류는 함수 템플릿클래스 템플릿 두 가지가 있다.

 

  • 함수 템플릿

: 하나의 함수를 모든 형의 변수에 대해 적용할 수 있게 정의할 수 있다.

 

함수의 정의와 선언

template<class T>
template<typename T>

위에 있는 것은 템플릿 전위문(prefix)이라고도 한다.

두 표현 모두 같은 의미이다. class나 typename 모두 사용 가능하다. (typename 키워드는 클래스를 생성 할 때 활용하는 class 키워드와 혼동되지 않도록 나중에 추가된 키워드이다)

 

뒤따라 나오는 함수 정의나 선언이 템플릿이며 T는 형 매개변수임을 컴파일러에게 말하는 것이다. 문맥상 class란 단어가 실제로 의미하는 것은 형이다.

 T라는 형 매개변수는 클래스이든 클래스가 아니든 임의의 형으로 대체될 수 있다.

 

 

템플릿 사용 예

prefix와 템플릿 정의

 

예제 swapValues 함수 : 두 변수의 형이 같은 한, 서로 값을 교환하는 함수

template<class T>
void swapValues(T& variable1, T& variable2)
{
	T temp;
	temp = variable1;
	variable1 = variable2;
	variable2 = temp;
}

위에 정의된 swapValues함수가 여러가지 다른 형태의 자료형(int, double, string)에 대하여 동작을 하게 된다.

// 컴파일러는 지금도 템플릿에 대해 문제점을 갖고 있다. 작성한 템플릿이 거의 모든 컴파일러에서 작동되게 하려면 템플릿이 사용되는 파일에 템플릿 정의를 두되 템플릿이 사용되기 이전 위치에 두어야 한다.

 

오버로딩 구현

템플릿이 아니라 오버로딩으로 구현하고자 했다면 아래와 같이 각각의 변수형에 따라 각각의 함수를 정의해주어야 한다.

void swapValues(int& variable1, int& variable2)
{
	int temp;
	temp = variable1;
	variable1 = variable2;
	variable2 = temp;
}

void swapValues(string& variable1, string& variable2)
{
	string temp;
	temp = variable1;
	variable1 = variable2;
	variable2 = temp;
}

 

템플릿 사용

// 1. 예시 - int
int num1 = 1, num2 = 2;
swapValues(num1, num2);           // 허용
swapValues<int&,int&>(num1,num2); // 허용 - 자료형 명시


// 2. 예시 - string
string str1 = "hi", str2 = "bye";
swapValues(str1, str2);                    // 허용
swapValues<string&,string&>(str1,str2);    // 허용 - 자료형 명시


// 3. 예시 - wrong, 다른 인자 2개
int num3 = 2;
double num4 = 3.14;
swapValues(num3, num4);                     // 오류!! 

일반 함수 호출 사용과 같이 함수명(인자)를 적어주면 된다.

개발자의 코드 이해를 돕기 위해 template함수 앞에 어떤 자료형을 쓸 건지 < > 안에 표시해주는 것도 허용된다.

 

함수 템플릿의 인스턴스화

컴파일 과정 중에 해당 함수가 어떤 자료형으로 호출이 될지 결정이 될 때 실제 함수가 생성이 되도록 되어 있다. (해당 타입의 인스턴스 생성)

이렇게 생성된 인스턴스는 함수 템플릿에 해당 타입이 사용될 때마다 호출된다.

 

위에 예시 1, 예시2 코드에서 컴파일러는 들어오는 자료 형태를 각각 int&, string&로 추론한다.

예시 3의 경우, 컴파일러가 추론에 실패한다. 왜냐하면 2개의 인자가 자료형이 다르기 때문이다.

 

 

  • 함수 템플릿 사용 예제 - 각기 다른 자료형의 인자

두 개 이상의 다른 자료형에 대한 템플릿 선언은 아래와 같다.

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

print<string,int>("apple",5);
print<string,string>("hello","world");

string name = "개발자라면";
int num = 1;
print<string,int>(name,num);

 

 

알고리즘 추상화

: 알고리즘 추상화를 사용하고 있다고 말할 때 의미하는 것은 부수적으로 따르는 세세한 것들은 무시하고 알고리즘의 실제적으로 중요한 부분에만 집중할 수 있도록 아주 일반적인 방법으로 알고리즘을 표현하고 있다는 것이다.

간단한 예) swapValues 함수에서 보았듯이 어떤 형의 두 변수에 대해서도 적용시켜 두 변수의 값을 교환하는 매우 일반적인 알고리즘이 있다. C++에선 함수 템플릿을 사용하여 이러한 일반적인 알고리즘을 표현할 수 있다. 

 

 

 

 

 

 

참고

책 "객체지향 원리로 이해하는 Absolute c++"

위키피디아 "템플릿(C++)"

반응형