Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

IT Language 연습실

template (1) 함수 ver 본문

C++

template (1) 함수 ver

akongman 2024. 2. 21. 16:14

저번에 문득 생각난게 template <typename B>  비슷하게 사용해봤던 기억이 난다. 이것이 template 이였다니...

다름이 아니라. 오늘 템플릿에 대해서 알아보려고 그런다. 우선 공부했던

함수 템플릿에 대해서 알아보자.

 

템플릿. 템플릿이라는 것은 모형이라고 말한다.

모형에는 사용 용도가 다 있고, 사용 용도를 어떠한 방식으로 사용하냐는 정해져 있지 않다.

 

우리 어린시절 수학시간에 모형자를 사용했던 기억이 한번씩 있지 않은가? 

☆모형의 모형자를 노란 색상의 연필로 모형을 따라 그린다면 노란 ☆이 나올것이다. 

☆모형의 모형자를 빨간 색상의 연필로 모형을 따라 그린다면 빨간 ☆이 나올것이다.

 

즉, 모형의 기능은 있는데 사용 용도 어떤 색상의 연필을 쓸지는 모른다.

 

이것을 우리가 공부하고 있는 언어의 함수로 좀 이입해보면.

함수의 기능은 정의가 되어 있는데 어떤 자료형으로 사용할지는 모른다는 것이다.

따라서 자료형을 골라 함수의 기능을 사용하겠다 라는 의미이다.

 

이것이 바로 함수 템플릿의 개념이다.

 

함수 템플릿의 등장은 아마도 이러한 것이 아닐까? 유추해볼 수 있다.

 

예를들어 

int function(int num, int num2)  { return  num + num2 ; } 

같은 함수가 정의되어 있다고 하자. 

위 함수는 덧셈의 기능을 갖고 있고 자료형은 int 이다. 

그런데 덧셈의 기능은 유지하는데 double 형을 연산하고 싶은 것이다. 그럼 정수형 int 로는 double 형의 연산이 올바르게 진행되지 않아 

double function( double num, double num2)  { return  num + num2 ; } 이라는 함수를 또 한번 정의해줘야 한다.

 

즉, 이렇게 자료형에 맞게 함수 기능을 사용하려면 매번 자료형에 맞게 정의해줘야 한다는 점이 불편하다는 것이다.

그럼 어떤 자료형이 올지는 모르지만 자료형에 따라서 함수 기능을 입력 받을 수 있다면 얼마나 좋을까? 

여기서부터 템플릿은 시작되는 것이다.

 

T function( T num, T num2) { return num + num2 }; 

위와 같이 우리가 아는 자료형이 아닌 완전 엉뚱하게도 T 라는 임의에 문자를 입력하였다.

그렇다. 사실 T는  <typename T> 라는 곳으로부터 시작된 것인데

이가  뜻하는 바가.  앞으로 자료형의 이름으로 T라고 사용할거에요. 라는 의미이다.

 

그럼 여기서 무슨 자료형인데? 라고 생각할 수 있는데 바로 그거다!!

무슨 자료형인지 모른다. 

 

그러니까 무슨 자료형인지 모르지만 일단 T라는 자료형으로 쓸건데 왜 그렇게 쓰냐면 

자료형 타입에 맞는 기능을 사용할 수 있게 할 template 함수를 만들거라서 그래요! 

따라서  컴파일러에게 template <typename T >라고 명시해줘야한다.

 

그럼 다 합쳐서 

 

template <typename T >

T function( T num, T num2) { return num + num2 }; 

 

위 문장이 완성이 된다.

위 문장이 함수 템플릿이다. 함수 템플릿의 한쌍의 문장이다.

 

그럼 이제 함수를 호출하는 과정에서 어떤 자료형으로 쓸지만 명시해주면 된다. 

그 작업은 다음과 같다.

 

std::cout<< function <int> ( 10, 20 ) ;

std::cout<< function <double> (1.1, 1.2);

 

위 코드를 보면 바로 눈에 띄게 알 수 있을것이다. <int> <double> 이러한게 있다.

맞다. 바로 어떤 자료형을 사용할지 명시를 해주는 것이다.

 

그런데 사실 <int> <double>은 생략해줘도 자료형에 맞는 기능을 사용할 수 있다.

즉 일반 함수처럼 사용해도 결과는 같다는 얘기이다. 

std::cout<< function ( 10, 20 ) ;

std::cout<< function (1.1, 1.2);

위와 같이 말이다.

 

왜 그러냐면 함수를 호출하고 인자를 전달하는 과정에서 컴파일러에게 고맙게도 전달되는 인자의 자료형을 알아서 판단하고 전달되는 인자의 자료형에 맞게 함수 템플릿으로 가 템플릿 함수를 생성한다.

 

( 함수 템플릿 - 함수를 만드는 템플릿이다.)  >> 즉 무슨 자료형인지 모르는 함수를 만들겠다. (사용자, 개발자)

( 템플릿 함수 - 템플릿 기반으로 만들어진 함수) > 컴파일러가 함수를 통하여 자료형에 맞는 함수를 만든 것. (컴파일러)

 

즉 우리가 정의한 함수 템플릿을 기반으로 컴파일러가 템플릿 함수를 만들었다라는 것인데

자료형을 명시를 해준다면 그 명시를 해준 자료형에 맞는 템플릿 함수를 생성하지만 

명시를 해주지 않았다면 전달되는 인자의 타입을 판단하여 그에 맞는 템플릿 함수를 생성해준다라는 것이다.

 

그럼 여기서 질문이 있을 것이다.

그러면 함수를 호출할때마다 템플릿이 생성되는건가요?

 

그건 아니다. 

 

만약 

std::cout<< function <int> ( 10, 20 ) ; 라고 호출을 했다면 컴파일러는 int 자료형의 템플릿 함수를 생성했다.

 

그 예시가 

int function<int>( int num, int num2) { return num + num2 }; 

위처럼 템플릿 함수가 만들어졌다는 것이다

 

그런데 두번째로

std::cout<< function <int> ( 30, 20 ); 라고 또 호출을 했다면 이미 생성된 템플릿 함수에  인자가 전달되고

그 값이 계산된다.

 

즉 한번 생성됐다면 그 생성된 함수를 사용한다는 것이다.

#include <iostream>

template <typename t>

t add (t a, t b) { 
    return a+b;
}

// int add (int a, int b) { return a+b}; // 인트형 덧셈 함수를 만들었어,
// double add (double, a double b) {return a+b}; //더블형 덧셈 함수를 만만들었어

/* 근데 이렇게 각각 쓰기에는 너무 불편하니까 자료형이 없는 함수를 하나 만들어 놓고 
그 자료형을 명시해줘서 하나의 함수의 정의로 자료형에 맞는 연산을 할 수 있게 사용하자! 
템플릿 ( 모형 ) 기능은 있는데 자료형이 없는 것. 
템플릿을 이용하는 것 
템플릿이 자료형에 맞는 함수를 각각 만들고 자료형에 맞는 함수를 호출해준다. */

int main() { 
    std::cout<<add<int>(10,20)<<std::endl; // int 함수 생성하고 호출 
    std::cout<<add<double>(1.1,1.1)<<std::endl; // double 함수 생성하고 호출 
    /* 템플릿은 위 함수를 만들고 호출한거야 */
    
    std::cout<<add(30,40)<<std::endl;
    std::cout<<add(2.2,2.2) <<std::endl; 
    /*위 함수들은 <int> or <double> 이라는 자료형의 명시없이 일반함수처럼 호출하였다.
    근데 이가 실행이 되는 이유는 컴파일러가 전달되는 인자의 자료형을 알아서 판단하고 
    그 자료형에 맞는 함수를 호출하여 계산했기 때문이다.*/
}

 

위 부분들을 정리한 문장들이다.

'C++' 카테고리의 다른 글

template (3) 클래스 ver  (0) 2024.02.22
template (2) 함수 ver  (0) 2024.02.21
cout, endl, cin의 정체  (0) 2024.02.17
상속(3)  (0) 2024.02.13
상속(2)  (0) 2024.02.13