본문 바로가기
C++

함수 템플릿!!!

by 상레알 2009. 2. 17.

이 책에서는 템플릿을 모형자에 비유하여 설명하을 한다.  모형자는 기능은결정되어 있는 반면에 색은 결정되어 있지 않다는게 특징이다.  "기능은 결정되어(정의되어) 있는 반면, 색은 결정되어 (정의되어) 있지 않다."

예를 들어서 원을 그릴 수 있는 모형자가 있다고 가정해 보자. 이 모형자의 기능은. 원을 그리는 것이다. 단! 그려지는 원의 색은 결정되어 있지 않다. 그렇다면 무엇에 의해서 색깔이 결정는가? 그림을 그리는 순간에 사용되는 펜에 의해서 색이 결정된다.

-> 예를 들어서 개념을 이해 하자~

ex)  int Add(int a, int b)
{
      return a+b;
}
위 함수는 두개의 데이터를 더하는 기능을 가지고 있다. 뿐만 아니라, int 형 정수로 덧셈의 대상도 정해져 있다. 즉 대상이 되는 데이터의 자료형도 정해져 있는 것이다. 만약에 이 함수를 템플릿으로 구현하게 된다면(템플릿화 한다면) 자료형은 결정되지 않는다. 마치 모형자의 색이 결정되어 있지 않는 것처럼-말이다.

=> 템플릿화
T Add( T a , T b)
{
       return a+b;
}

- 앞에서 선언한 Add 함수와 비교해 보면, int라는 선언이 모두 T 라는 선언으로 바뀌었음을 알 수 있다. 즉, 자료형을 결정짓지 않겟다는 뜻이다. 문제는  컴파일러가 이것을 인식하지 못한다는데 있다. 컴파일러는 우리들에게 이렇게 물어볼 것이다.(컴파일 에러를 통해서).
"T 라는 이름의 클래스는 정의한 바가 없는데 무슨뜻입니까??"
->따라서 컴파일러에게 다음과 같은 메시지를 전달해야 한다.
"T는 자료형을 결정짓지 않겟다는 의미로 사용한 것입니다. 즉 함수를 템플릿화하기 위해서 사용된 것이다."

====>>
template <typename T>
T Add(T a,T b)
{
     return a+b;
}

첫번쨰 줄에 template <typename T>   라는 문장이 존재한다. 이 문장은
"T 라는 이름(type name)에 대해서 다음에 정의하는 대상을 템플릿으로 선언한다."   라는 말이다.

- 참고  선언 "template <typename T>" 에서 typename을 대신해서 class 라는 키워들르 사용해도 된다.(과거에 주로 사용되던 방식이다.)  즉   "template <typename T>"  ==  "template <class T>"

-템플릿으로 정의된 함수의 자료형이 결정되는 시점은 인자가 전달되는 순간이다.


함수 템플릿-!!!!

-함수를 템플릿으로 선언하였다. 그렇다면 이것의 정확한 명칭은 무엇일까?
1. 함수 템플릿    2. 템플릿 함수      = >   1.함수 템플릿이다.!!

함수템플릿이라고 부른다는 것은 템플릿임을 강조하는 것이다.(함수가 아니라는 뜻이 아니다.) 함수이기 전에 템플릿의 정의해 해당된다는 것을 의미한다.

- 만약에 타입이 한가지가 아니라 두가지 이상이라면 어떻게 될까??

바로 앞에서 햇던대로

template <typename T>
void Showdata(T a , T b)
{
       cout<<a<<b<<endl;
}

여기에서 a는 int 형이고  b가 double 형이라면?? 
-> 컴파일 오류가 발생한다.

이것을 극복하기 위해서는

template<typename T1, typename T2>  
정의를 이렇게 바꾸면 2개의 타입에 대하여 탬플릿을 선어하게 되는것이다.
-> " T1과 T2라는 이름(type name )에 대해서 다음에 정의하는 대상을 템플릿으로 선언한다."

함수 템플릿의 특수화

함수 템플릿의 특수화는 템플릿에서의 함수 오버로딩과 비슷한거 같다...단편적인 예만 봐서 그런가 ㅡ.ㅡ;;

예를 들어서 설명하겟다.

template <typename T> //함수 템플릿 정의
int Sizeof(T a)
{
       return  sizeof(a)
}

-> 그런대 정수로 입력을하면 메모리 크기를 리턴하겟지만.  만약.  char * 으로 문자열을 인자로 넘겨 받는다면??
내용이 무엇이든간에  포인터의 크기 4 바이트가 리턴이 될것이다. - 전달되는 인자가 문자열을 가리키는 포인터일 경우, 문자열의 길이를 리턴해 주기를 원했을 것이다 .  템플릿 특수화라는 문법적요소는 이것을 해결할수 잇게한다.

template<typename T>
int Sizeof(T a)
{
    return sizeof(a);
}

template<>     //함수 템플릿 특수화 선언!
int Sizeof(char* a)
{
       return strlen(a);
}

2번째 템플릿 선언을 통해서  char 포인터형(char *)이라면, 그 2번째 정의된 함수가 호출될것이다. 2번째 정의된 함수는 char 포인터형(char *)에 대해서만 특수화 되어 있기 때문이다.
그리고 template<>은 특수화된 함수임을 선언하는 것이다.

보통은 template<>
         int Sizeof(char* a)    => 이라고 선언을
보통 선언1 처럼 한줄에 표현하는 것이 보통이다.
선언1: template<> int Sizeof(char* a)
이문장은 다음 과같이 선언 2: 선언3 으로도 가능한다.
선언2: template<> int Sizeof<>(char* a)
선언3: template<> int Sizeof<char*>(char* a)

선언 3의 형태가 가장 정확한 표현이고, 선언 1과 2는선언 3을 줄여서 표현한 형태이다. 그러므로 선언 3의 표현방법도 기억하고 있기 바란다.고하는군...






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

C++ 예외 처리  (0) 2009.02.18
use of class template requires template argument list ->컴파일 에러  (0) 2009.02.18
클래스 템플릿!  (0) 2009.02.18
임시 객체에 대하여....  (0) 2009.02.16
string 클래스 디자인  (0) 2009.02.16
oop 프로젝트 8단계 중...  (0) 2009.02.12
배열의 인덱스 연산자 오버로딩  (0) 2009.02.10
cout / cin / endl 에 대하여...  (0) 2009.02.10
단항 연산자의 오버로딩  (0) 2009.02.09
연산자 오버로딩  (0) 2009.02.06