함수 템플릿을 정의하고 사용하다가 특수한 매개 변수에 대해서만 다른 동작을 하고 싶은 경우에는 템플릿 특수화 기능을 사용할 수 있다.
예를 들어서 아래와 같은 코드에서 배열 원소의 타입이 char인 경우에는 문자열로 출력하고 싶다고 가정하자. 이런 경우는 template<>을 사용하면 된다.
template <typename T> // 함수 템플릿으로 정의
void print_array(T[] a, int n)
{
예를 들어서 아래와 같은 코드에서 배열 원소의 타입이 char인 경우에는 문자열로 출력하고 싶다고 가정하자. 이런 경우는 template<>을 사용하면 된다.
template <typename T> // 함수 템플릿으로 정의
void print_array(T[] a, int n)
{
for(int i=0;i<n; i++)
cout << a[i] << " ";
cout << endl;
cout << a[i] << " ";
cout << endl;
}
template <> // 템플릿 특수화
void print_array(char[] a, int n) // 매개 변수가 char인 경우에는 이 함수가 호출된다.
{
template <> // 템플릿 특수화
void print_array(char[] a, int n) // 매개 변수가 char인 경우에는 이 함수가 호출된다.
{
cout << a << endl;
}
(http://blog.naver.com/koreanvsun?Redirect=Log&logNo=70095465365)
함수의 오버로딩(overloading)이랑 비슷한듯..
#템플릿이란?
기능은 결정되어 있으나 자료형이 정해져 있지 않는 것을 템플릿 이라고 한다. 예을 들어 계산기 프로그램의 덧셈 함수를 만들때 해당 자료형에 맞는 함수를 오버로딩해야 한다. 하지만 템플릿으로 만든 함수는 그럴 필요가 없이 하나의 함수로 모두 사용이 가능하다.
#함수 템플릿(Function Template)
template <typename 식별자> 함수() // 함수 앞에 사용. 식별자는 자료형을 의미하는 것으로 적용할 자료형에 사용하면 된다.
참고사항> typename을 class 로 대체 가능하다.
ex> template <class T>
ex>
template <typename T> // 두줄로 해도 상관 없다.
T Add(T a, T b)
{
return a+b;
}
int p = Add(1,3); // int형 4을 반환 한다.
int p = Add<int>(1,3); // 명시적으로 <자료형>을 같이 써주어도 된다. 위와 동일하게 동작한다.
double q = Add(1.1,3.3); // double형 4.4을 반환한다.
CString str1 = "abcd", str2 = "EFGH", str;
str = Add(str1, str2); // CString형 "abcdEFGH"를 반환 한다.
위와 같이 자료형은 다르지만 하나의 함수로 이것을 가능하게 해주는 것이 템플릿이다. 물론 자료형이 같다고 되는 건 아니다. 예로 char*의 경우 포인터끼리 + 한다면 우리가 원하는 값이 나오지 않을 것이다. 이때 사용하는 것이 템플릿 특수화이다. CString 의 경우에는 + 연산자오버로딩이 되어있기 때문에 가능하다.
#클래스 템플릿(class template)
템플릿은 컴파일시 내부적으로 템플릿 인자로 넘어온 자료형을 적용하여 새로운 클래스를 하나 생성하게 된다. 그리고 컴파일러는 생성한 클래스를 가지고 작업을 수행하게 된다. 템플릿 클래스는 선언시 자료형에 상관없는 범용클래스로 만든후 객체 생성시 자료형을 지정해주면, 지정한 자료형에 맞는 클래스 인스턴스가 생성된다.
template <typename 식별자> 클래스 //클래스 정의
{
//내용
};
template <typename 식별자>
void 클래스명<식별자>::멤버함수() // 맴버 함수 구현
{
//내용
}
ex>
template <typename T>
class Stack
{
private:
int size_;
int top_;
T *pMem_;
public:
Stack(int size) : size_(size), top_(-1){
pMem_ = new T [size];
};
~Stack(){
delete [] pMem_;
};
void push(T v) // 클래스 정의 안에 함수정의와 구현을 동시에
{
pMem_[++top_] = v;
};
T pop(); // 클래스 정의 안에 함수정의만
};
template <typename T>
T Stack<T>::pop() // 위부에서 함수 구현
{
return pMem_[top_--];
}
Stack<int> s1; //클래스 인스턴스를 생성시 typename에 해당하는 자료형을 명시해야 된다. 이는 해당 자료형을 알아야 메모리 할당을 할수 있기 때문이다.
템플릿 인자에 타입 이외의 값도 들어 갈수 있다.
template <typename 식별자, 자료형 식별자> 클래스 //클래스 정의
{
//내용
};
template <typename 식별자, 자료형 식별자>
void 클래스명<식별자, 식별자>::멤버함수() // 맴버 함수 구현
{
//내용
}
ex>
template <typename T, int N>
class someClass
{
public:
someClass();
};
template<typename T, int N> someClass<T, N>::someClass()
{
T v = N;
}
주의> 클래스 템플릿 사용시 하나의 헤더파일안에 템플릿 클래스의 구현과 선언부분을 모두 써넣어줘야 한다. 그렇지 않다면 링크시 구현부분을 찾지못하며 에러가 난다.
#템플릿(class template)의 특수화
특별한 자료형에 대해서 다른 기능으로 처리를 하고자 할때 사용되는 방법이다.
-함수를 특수화 하는 방법
template <> 함수() // 함수 앞에 사용. 식별자를 넣지 않고 함수에 자료형을 명시한다.
template <> 함수<>() // 이렇게도 사용 가능하다.
ex>
template<typename T>
int Sizeof(T a)
{
return sizeof(a);
}
template<>
int Sizeof(char* a) //char* 형으로 매개변수가 오면 해당 함수가 호출된다.
{
return strlen(a);
}
int i = 1234;
char sz[] = "12345";
int len1 = Sizeof(i); // 일반 템플릿으로 4을 반환한다.
int len2 = Sizeof(sz); // 템플릿 특수화로 5을 반환한다.
-클래스를 특수화하는 방법
함수 특수화와 같이 특정 자료형에 대해서 특수화 시킨다.
template <typename 식별자> 클래스 //클래스 정의
{
//내용
};
template <> 클래스<자료형> //클래스 정의 특수화
{
//내용
};
참고사항> 특수화된 클래스는 전혀 별개의 클래스이다.
ex>
template <typename T>
class Stack // 일반 클래스 템플릿
{
public:
T Func(){};
};
template <>
class Stack<int> // 특수화 클래스 템플릿
{
public:
int Func(float v){};
};
template <>
int Stack<int>::Func() // 특정 멤버함수만 특수화가 가능하다.
{
}
Stack<double> s1; // double형 클래스를 생성한다.
Stack<int> s2; // int형 특수화 클래스를 생성한다.
-그 이외의 특수화 예
#템플릿의 원리
int p = Add(1,3) 의 경우 해당 변수의 자료형에 맞추어 컴파일러가 Add 함수를 생성한다.
int Add(int a, int b)
{
return a+b;
}
(http://blog.naver.com/pointer98?Redirect=Log&logNo=150059872344)
(http://blog.naver.com/koreanvsun?Redirect=Log&logNo=70095465365)
함수의 오버로딩(overloading)이랑 비슷한듯..
#템플릿이란?
기능은 결정되어 있으나 자료형이 정해져 있지 않는 것을 템플릿 이라고 한다. 예을 들어 계산기 프로그램의 덧셈 함수를 만들때 해당 자료형에 맞는 함수를 오버로딩해야 한다. 하지만 템플릿으로 만든 함수는 그럴 필요가 없이 하나의 함수로 모두 사용이 가능하다.
#함수 템플릿(Function Template)
template <typename 식별자> 함수() // 함수 앞에 사용. 식별자는 자료형을 의미하는 것으로 적용할 자료형에 사용하면 된다.
참고사항> typename을 class 로 대체 가능하다.
ex> template <class T>
ex>
template <typename T> // 두줄로 해도 상관 없다.
T Add(T a, T b)
{
return a+b;
}
int p = Add(1,3); // int형 4을 반환 한다.
int p = Add<int>(1,3); // 명시적으로 <자료형>을 같이 써주어도 된다. 위와 동일하게 동작한다.
double q = Add(1.1,3.3); // double형 4.4을 반환한다.
CString str1 = "abcd", str2 = "EFGH", str;
str = Add(str1, str2); // CString형 "abcdEFGH"를 반환 한다.
위와 같이 자료형은 다르지만 하나의 함수로 이것을 가능하게 해주는 것이 템플릿이다. 물론 자료형이 같다고 되는 건 아니다. 예로 char*의 경우 포인터끼리 + 한다면 우리가 원하는 값이 나오지 않을 것이다. 이때 사용하는 것이 템플릿 특수화이다. CString 의 경우에는 + 연산자오버로딩이 되어있기 때문에 가능하다.
#클래스 템플릿(class template)
템플릿은 컴파일시 내부적으로 템플릿 인자로 넘어온 자료형을 적용하여 새로운 클래스를 하나 생성하게 된다. 그리고 컴파일러는 생성한 클래스를 가지고 작업을 수행하게 된다. 템플릿 클래스는 선언시 자료형에 상관없는 범용클래스로 만든후 객체 생성시 자료형을 지정해주면, 지정한 자료형에 맞는 클래스 인스턴스가 생성된다.
template <typename 식별자> 클래스 //클래스 정의
{
//내용
};
template <typename 식별자>
void 클래스명<식별자>::멤버함수() // 맴버 함수 구현
{
//내용
}
ex>
template <typename T>
class Stack
{
private:
int size_;
int top_;
T *pMem_;
public:
Stack(int size) : size_(size), top_(-1){
pMem_ = new T [size];
};
~Stack(){
delete [] pMem_;
};
void push(T v) // 클래스 정의 안에 함수정의와 구현을 동시에
{
pMem_[++top_] = v;
};
T pop(); // 클래스 정의 안에 함수정의만
};
template <typename T>
T Stack<T>::pop() // 위부에서 함수 구현
{
return pMem_[top_--];
}
Stack<int> s1; //클래스 인스턴스를 생성시 typename에 해당하는 자료형을 명시해야 된다. 이는 해당 자료형을 알아야 메모리 할당을 할수 있기 때문이다.
템플릿 인자에 타입 이외의 값도 들어 갈수 있다.
template <typename 식별자, 자료형 식별자> 클래스 //클래스 정의
{
//내용
};
template <typename 식별자, 자료형 식별자>
void 클래스명<식별자, 식별자>::멤버함수() // 맴버 함수 구현
{
//내용
}
ex>
template <typename T, int N>
class someClass
{
public:
someClass();
};
template<typename T, int N> someClass<T, N>::someClass()
{
T v = N;
}
주의> 클래스 템플릿 사용시 하나의 헤더파일안에 템플릿 클래스의 구현과 선언부분을 모두 써넣어줘야 한다. 그렇지 않다면 링크시 구현부분을 찾지못하며 에러가 난다.
#템플릿(class template)의 특수화
특별한 자료형에 대해서 다른 기능으로 처리를 하고자 할때 사용되는 방법이다.
-함수를 특수화 하는 방법
template <> 함수() // 함수 앞에 사용. 식별자를 넣지 않고 함수에 자료형을 명시한다.
template <> 함수<>() // 이렇게도 사용 가능하다.
ex>
template<typename T>
int Sizeof(T a)
{
return sizeof(a);
}
template<>
int Sizeof(char* a) //char* 형으로 매개변수가 오면 해당 함수가 호출된다.
{
return strlen(a);
}
int i = 1234;
char sz[] = "12345";
int len1 = Sizeof(i); // 일반 템플릿으로 4을 반환한다.
int len2 = Sizeof(sz); // 템플릿 특수화로 5을 반환한다.
-클래스를 특수화하는 방법
함수 특수화와 같이 특정 자료형에 대해서 특수화 시킨다.
template <typename 식별자> 클래스 //클래스 정의
{
//내용
};
template <> 클래스<자료형> //클래스 정의 특수화
{
//내용
};
참고사항> 특수화된 클래스는 전혀 별개의 클래스이다.
ex>
template <typename T>
class Stack // 일반 클래스 템플릿
{
public:
T Func(){};
};
template <>
class Stack<int> // 특수화 클래스 템플릿
{
public:
int Func(float v){};
};
template <>
int Stack<int>::Func() // 특정 멤버함수만 특수화가 가능하다.
{
}
Stack<double> s1; // double형 클래스를 생성한다.
Stack<int> s2; // int형 특수화 클래스를 생성한다.
-그 이외의 특수화 예
#템플릿의 원리
int p = Add(1,3) 의 경우 해당 변수의 자료형에 맞추어 컴파일러가 Add 함수를 생성한다.
int Add(int a, int b)
{
return a+b;
}
(http://blog.naver.com/pointer98?Redirect=Log&logNo=150059872344)
'study' 카테고리의 다른 글
must know (0) | 2010.10.21 |
---|---|
SVN TAG (0) | 2010.10.14 |
Frame buffer (0) | 2010.08.20 |