Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

SYDev

C++ Chapter 13-1 : 템플릿(Template)에 대한 이해와 함수 템플릿 본문

Programming Lang/C++

C++ Chapter 13-1 : 템플릿(Template)에 대한 이해와 함수 템플릿

시데브 2023. 7. 27. 16:24

함수 템플릿

  • 함수 템플릿(function template)은 함수를 만드는 도구이며, 하나의 함수로 다양한 자료형의 함수를 호출할 수 있다.
template <typename T>	// template <class T>도 가능
T Add(T num1, T num2)
{
    return num1+num2;
}

 위 함수의 정의가 함수 템플릿의 예시이다. 

  • 함수의 기능 : 덧셈
  • 대상 자료형 : 결정되지 않음

 이처럼 같은 기능을 하는 함수로 여러 자료형을 받고 반환할 수 있게 해주는 것이 함수 템플릿이다.

 

 아래 예제를 살펴보자.

#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;  //T를 int로 해서 만들어진 Add 함수 호출, int형 자료에 대한 함수는 이때만 만들어짐
    cout<< Add<double>(2.9, 3.7)<<endl; //T를 double로 해서 만들어진 Add 함수 호출, double형 자료에 대한 함수는 이때만 만들어짐
    cout<< Add<int>(3.2, 3.2)<<endl;    //앞서 만들어놓은 int형 함수 호출
    cout<< Add<double>(3.14, 2.75)<<endl;   //앞서 만들어놓은 double형 함수 호출

    return 0;
}
35
6.6
6		-> int형 함수에 double형 자료를 넣어 값의 손실 발생
5.89

 위와 같이 함수 템플릿 기반의 함수는 Add<자료형>(매개변수)로 호출할 수 있다. 

 

 이때, 함수는 다음의 형태로 호출되는데, 이를 템플릿 함수(template function)라고 한다.

int Add<int>(int num1, int num2)
{
    return num1+num2;
}

double Add<double>(double num1, double num2)
{
    return num1+num2;
}

 물론, 위 함수 호출문에서 <자료형>부분을 빼고 일반 함수를 호출하듯이 Add(매개변수)의 형태로 호출할 수도 있다. 이 경우에는 컴파일러가 알아서 전달받은 인자의 자료형을 참조하여 호출될 함수의 자료형을 결정한다.

 

 이에 따라 위 예제의 호출문 중 하나인 Add<int>(3.2, 3.2)를 Add(3.2, 3.2)로 바꾸면 실행의 결과로 6.4가 출력된다.

 

 + 함수를 호출할 때마다 함수를 생성하는 것이 아닌 자료형에 따라 최초 호출시에만 함수 생성, 컴파일 시간이 길어질 뿐 실행 시간은 똑같음.

 

함수 템플릿과 템플릿 함수

  • 함수 템플릿 -> 함수를 만드는데 사용되는 템플릿
  • 템플릿 함수 -> 템플릿을 기반으로 만들어진 함수   

 이렇게 만들어진 템플릿 함수는 일반 함수와 구분되는데, 예제를 통해 살펴보자.

#include <iostream>
using namespace std;

template <typename T>

T Add(T num1, T num2)
{
    cout<<"T Add(T num1, T num2)"<<endl;
    return num1+num2;
}

int Add(int num1, int num2)
{
    cout<<"Add(int num1, int num2)"<<endl;
    return num1+num2;
}

double Add(double num1, double num2)
{
    cout<<"Add(double num1, double num2)"<<endl;
    return num1+num2;
}

int main(void)
{
    cout << Add(5, 7) << endl;
    cout << Add(3.7, 7.5) << endl;
    cout << Add<int>(5, 7) << endl;
    cout << Add<double>(3.7, 7.5) << endl;

    return 0;
}
Add(int num1, int num2)
12
Add(double num1, double num2)
11.2
T Add(T num1, T num2)
12
T Add(T num1, T num2)
11.2

 

둘 이상의 형(Type)에 대해 템플릿 선언하기

  • 함수 템플릿의 정의에도 다양한 자료형 선언이 가능하다.
  • 둘 이상의 type에 대해 템플릿을 선언할 수 있다. 

 예제를 통해 자세히 살펴보자.

#include <iostream>
using namespace std;

template <class T1, class T2>   //둘 이상의 template type 명시 가능

void ShowData(double num)   //함수 템플릿의 매개변수, 반환 자료형도 기본 자료형으로 선언 가능
{
    cout<<(T1)num<<", "<<(T2)num<<endl; //cout<<T1(num)<<", "<<T2(num)<<endl;과 같은 문장
}

int main(void)
{
    ShowData<char, int>(65);    //아스키 코드 65번 'A'가 출력
    ShowData<char, int>(63);    //아스키 코드 63번 '?'가 출력
    ShowData<char, double>(126.9);  //아스키 코드 126번 '~'가 출력
    ShowData<short, double>(69.2);
    ShowData<short, double>(70.4);

    return 0;
}
A, 65
?, 63
~, 126.9
69, 69.2
70, 70.4

 

함수 템플릿의 특수화(Specialization)

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

template <typename T>
T Max(T a, T b)
{
    return a > b ? a : b ;  
    /*
    삼항 연산자 -> (조건식) ? 반환값1 : 반환값2
    조건식의 결과값이 참(1)이면 반환값1 반환, 거짓(0)이면 반환값2 반환
    */
}

int main(void)
{
    cout << Max(11, 15) << endl;
    cout << Max('T', 'Q') << endl;
    cout << Max(3.5, 7.5) << endl;
    cout << Max("Simple", "Best") << endl;

    return 0;
}
15
T
7.5
Simple
  • 위 예제의 함수 템플릿 Max는 전달된 두 데이터 중 큰 값을 반환하도록 정의되어있다. 
  • 그러나, 15행같은 문자열이 대상으로 주어졌을 때는, 단순히 주소 값의 비교 결과만 나올 뿐이다. 이를 문자열 길이비교와 사전편찬의 순서, 두 가지의 형태로 비교해보자.
#include <iostream>
#include <cstring>
using namespace std;

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

template <>	//함수 템플릿 특수화
char* Max(char* a, char* b)
{
    cout<<"char* Max<char*>(char* a, char* b)"<<endl;
    return strlen(a) > strlen(b) ? a : b ;
}

template <>	//함수 템플릿 특수화
const char* Max(const char* a, const char* b)
{
    cout<<"const char* Max<const char*>(const char* a, const char* b)"<<endl;
    return strcmp(a, b) > 0 ? a : b ;
    /*
    strcmp(a, b)
    (1) a < b 인 경우에는 음수 반환

    (2) a > b 인 경우에는 양수 반환

    (3) a == b 인 경우에는 0을 반환 
    */
}

int main(void)
{
    cout << Max(11, 15) << endl;
    cout << Max('T', 'Q') << endl;
    cout << Max(3.5, 7.5) << endl;
    cout << Max("Simple", "Best") << endl;

    char str1[] = "Simple";
    char str2[] = "Best";
    cout << Max(str1, str2) << endl;

    return 0;
}
15
T
7.5
const char* Max<const char*>(const char* a, const char* b)
Simple
char* Max<char*>(char* a, char* b)
Simple
  • 함수 템플릿의 특수화가 진행된 함수의 경우에는 해당 자료형의 템플릿 함수를 별도로 만들지 않고 원래 있던 함수를 호출한다.

 


참고자료

 

[C언어/C++] strcmp, strncmp 함수(문자열 비교)에 대해서

안녕하세요 BlockDMask입니다.오늘은 c/c++에서 두개의 문자열이 같은지, 다른지 다르면 어떤식으로 다른지 검사할 수 있는 strcmp 함수. 문자열 비교 함수인 strcmp 함수를 알아 보려고 합니다. 오늘은

blockdmask.tistory.com

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 

[엑셀] Char() 함수에 할당된 문자 목록 (아스키 코드)

엑셀 CHAR() 함수에는 아스키 코드가 할당된다. (참고: 2017/07/11 - [엑셀] - [엑셀] Char()에 할당된 번호 알아보기, 연속되는 알파벳 채우기) 아스키 문자 테이블에 따라 CHAR(1) 부터 CHAR(127) 까지 다음과

lightblog.tistory.com

  • 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12