함수 템플릿(function template)은 함수의 일반화된 선언을 의미한다.
함수 템플릿을 사용하면 같은 알고리즘을 기반으로 하면서, 서로 다른 타입에서 동작하는 함수를 한 번에 정의할 수 있다.
이는 임의의 타입으로 작성된 함수에 특정 타입을 매개변수로 전달하면, C++ 컴파일러에서 해당 타입에 맞는 함수를 생성해주기 때문이다.
함수 템플릿은 다음과 같은 문법으로 사용할 수 있다.
template <typename 타입이름>
함수의 원형
{
// 함수 구현
}
C++98에서 추가된 typename
키워드는 이전에 class
키워드를 사용했다.
따라서 C++ 컴파일러는 템플릿 정의 내의 typename
키워드와 class
키워드를 같은 것으로 간주한다.
typename
키워드를 사용해 정의된 타입 이름은 함수의 원형과 본체에서 임의의 타입으로 사용할 수 있다.
typename
키워드로 정의된 매개변수에 어떠한 타입을 전달하면, 함수의 원형과 본체에서 정의된 타입은 모드 해당 타입으로 바뀌게 된다.
아래 예제는 여러 타입의 변수의 값을 서로 바꾸는 Swap()
함수를 함수 템플릿으로 작성한 예제이다.
#include <iostream>
using namespace std;
template <typename T>
void Swap(T &a, T &b);
int main()
{
int c = 2, d = 3;
cout << "c : " << c << ", d : " << d << endl;
Swap(c, d);
cout << "c : " << c << ", d : " << d << endl;
string e = "hong", f = "kim";
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;
}
c : 2, d : 3
c : 3, d : 2
e : hong, f : kim
e : kim, f : hong
함수 템플릿이 각각의 타입에 대해 처음으로 호출될 때, C++ 컴파일러는 해당 타입의 인스턴스(instance)를 생성한다.
생성된 인스턴스는 해당 타입에 대해 암시적으로 특수화된 템플릿 함수이다.
따라서 해당 인스턴스는 함수 템플릿에 해당 타입이 사용될 때마다 호출된다.
C++의 함수 템플릿은 특정 타입에 대한 명시적 특수화(explicit specialization)를 제공하여 특정 타입에 대해 특정한 동작을 정의할 수 있다.
컴파일러는 호출된 함수에 정확히 대응하는 특수화된 정의를 발견하면, 더 이상 테블릿을 찾지 않고 해당 정의를 사용한다.
Swap()
함수 템플릿에서 double
형에 대한 동작만 변경하기 위해 명시적 특수화를 사용한 예제이다.
#include <iostream>
using namespace std;
template <typename T> void Swap(T &a, T &b);
template <> void Swap<double>(double &a, double &b);
int main()
{
int c = 2, d = 3;
cout << "c : " << c << ", d : " << d << endl;
Swap(c, d);
cout << "c : " << c << ", d : " << d << endl;
double e = 1.234, f = 4.321;
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;
}
template <>
void Swap<double>(double &a, double &b)
{
return ;
}
c : 2, d : 3
c : 3, d : 2
e : 1.234, f : 4.321
e : 1.234, f : 4.321