함수 템플릿
함수를 만드는 도구, 다양한 자료형의 함수를 만들어 낼 수 있다.
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>(15, 20) <<endl; cout<< Add<double>(2.9, 3.7) <<endl; cout<< Add<int>(3.2, 3.2) <<endl; cout<< Add<double>(3.14, 2.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 |
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(15, 20) <<endl; cout<< Add(2.9, 3.7) <<endl; cout<< Add(3.2, 3.2) <<endl; cout<< Add(3.14, 2.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<char, int>(65); ShowData<char, int>(67); ShowData<char, double>(68.9); ShowData<short, double>(69.2); ShowData<short, double>(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 템플릿에 대한 이해와 함수 템플릿
'Software Development > C, C++' 카테고리의 다른 글
DALi code review - C++ 코드리딩, 람다 코드 이해하기 (0) | 2021.02.03 |
---|---|
[C++] std::remove & std::remove_if 이해하기 (0) | 2021.02.02 |
[C++]new, delete 연산자 오버로딩 (0) | 2019.01.13 |
[C++] 배열 인덱스 연산자 오버로딩 [] (1) | 2019.01.12 |
[C++] 연산자 오버로딩 - 디폴트 대입 연산자 (0) | 2019.01.12 |