Software Development/C, C++

[C++] 템플릿(Template)에 대한 이해와 함수 템플릿

huiyu 2019. 3. 10. 17:42

함수 템플릿

함수를 만드는 도구, 다양한 자료형의 함수를 만들어 낼 수 있다.

1
2
3
4
int Add(int num1, int num2)
{
  return num1 + num2;
}
cs

 - 위 함수의 기능 : 덧셈
 - 대상 자료형 : int형 데이터

위 함수를 템플릿 함수로 변경하자.

1
2
3
4
5
template <typename T>
T Add(T num1, T num2)
{
  return num1 + num2;
}
cs

 - template <typename T>
  : 이는 T라는 이름을 이용해서 아래에 선언된 함수를 템플릿으로 정의한다는 의미이다.
 - int을 T로 선언
  : T는 자료형을 결정짓지 않겠다는 의미로 사용한 것, 그래서 나중에 T를 대신해서 실제 자료형을 결정한다.

* typename을 대신해서 class를 사용해도 된다. 이 둘은 같은 의미이다. T대신 다른 문자를 사용해도 된다.
  - template <typename T>
  - template <class T>
  - C++ 초기엔 템플릿 선언에 키워드 class만 사용할 수 있었다. 그런데 이는 클래스 선언에 사용되는 키워드와 동일하다는 지적때문에  typename이라는 키워드도 사용할 수 있도록 정정되었다. 그러나 최근에 만들어진 C++관련 국내외 자료들을 보면 여전히 class가 많이 사용된다. 이유는 typename보다 class가 입력이 더 편해서이다. C++창시자도 class선언을 선호한다고 한다.

위와같이 템플릿 함수를 선언하게 되면, 컴파일러는 함수의 호출문장을 보면서 필요한 함수들을 만들어 낸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
 
template <typename T>
 
T Add(T num1, T num2)
{
  return num1 + num2;
}
 
int main(void)
{
  cout<< Add<int>(1520<<endl;
  cout<< Add<double>(2.93.7<<endl;
  cout<< Add<int>(3.23.2<<endl;
  cout<< Add<double>(3.142.75<<endl;
}
cs

- 13행 : Add<int>(15, 20)
  : 여기서 <int>가 의미하는 바는 다음과 같다.
   "T를 int로 해서 만들어진 Add 함수를 호출한다."

위 문장을 보는 순간 컴파일러는 다음의 형태로 함수를 하나 만든다.
그리고 인자 15와 20을 전달하며 아래 함수를 호출하게 된다.

1
2
3
4
int Add(int num1, int num2)
{
  return num1 + num2;
}
cs

이어 13행의 Add<double>(2.9, 3.7)을 만나게 되면 아래 함수를 만든다.
1
2
3
4
double Add(double num1, double num2)
{
  return num1 + num2;
}
cs

* 컴파일러는 템플릿으로 정의된 함수를 호출하게 되면, 호출시 호출하는 형태로 함수를 생성한다. 그 다음 호출시엔 이미 만들어진 함수를 호출할 뿐 새로 함수를 만들지 않는다. 즉, 함수는 자료형당 하나씩만 만들어진다.
* 컴파일 시 함수를 생성하기 때문에 컴파일 속도는 느려진다. 그러나 실행속도가 느려진 것은 아니다.

위 main()함수는 아래와 같이 일반함수 호출과 같은 방식으로 수정이 가능하다.
이는 전달되는 인자의 자료형을 참조하여 호출될 함수의 유형을 컴파일러가 결정하기 때문이다.

1
2
3
4
5
6
7
8
int main(void)
{
  cout<< Add(1520<<endl;
  cout<< Add(2.93.7<<endl;
  cout<< Add(3.23.2<<endl;
  cout<< Add(3.142.75<<endl;
}
 
cs

**함수 템플릿과 템플릿 함수

  - 함수 템플릿(function template) : 앞서보인 다음의 정의를 가리켜 '함수 템플릿'이라 한다.

1
2
3
4
5
template <typename T>
T Add(T num1, T num2)
{
  return num1 + num2;
}
cs

 - 템플릿 함수(template function) : 위의 템플릿을 기반으로 컴파일러가 만들어 내는 다음 유형의 함수들을 '템플릿 함수'라 한다.
  (템플릿 함수는 컴파일러에 의해 생성된 함수이기 때문에 '생성된 함수(Generated Function)'으로도 불린다.

1
2
3
4
5
6
7
8
9
int Add<int>(int num1, int num2)
{
  return num1 + num2;
}
 
double Add<double>(double num1, double num2)
{
  return num1 + num2;
}
cs


* 둘 이상의 형(Type)에 대해 템플릿 선언하기
  - 함수 템플릿을 정의할 땐 다양한 자료형을 기본으로 선언할 수 있으며, 둘 이상의 형(type)에 대해서 템플릿을 선언할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
template <class T1, class T2>
void ShowData(double num)
{
  cout<<(T1)num<<", "<<(T2)num<<endl;
}
 
int main(void)
{
  ShowData<charint>(65);
  ShowData<charint>(67);
  ShowData<chardouble>(68.9);
  ShowData<shortdouble>(69.2);
  ShowData<shortdouble>(70.4);
  return 0;
}
cs

- 4행 : 쉼표를 이용해 둘 이상의 템플릿 타입을 명시, typename대신 class 키워드 사용
- 5행 : 함수 템플릿의 매개변수를 기본 자료형으로 선언할 수 있다.
- 7행 : 인자로 전달된 num의 값을 T1과 T2로 명시되는 자료형으로 형 변환해서 출력한다.
- 12~16행 : 위의 함수 템플릿은 매개변수 형이 double로 선언되어있어 전달되는 인자를 통해서 T1과 T2의 자료형을 결정짓지 못한다. 따라서 이러한 경우에는 템플릿 함수의 호출형식을 완전히 갖춰서 호출해야 한다.

[출력결과]
A, 65
C, 67
D, 68.9
69, 69.2
70, 70.4

[참고자료]
윤성우 열혈 C++ 프로그래밍 Chapter 13. 템플릿(Template), 13-1 템플릿에 대한 이해와 함수 템플릿

728x90