[C++] 템플릿(template)
        
        
      
REF : 윤성우의 열혈 C++
함수템플릿
- 함수템플릿은 다양한 자료형의 함수를 만들어낼 수 있다.
    
- 
        
int Add(int num1, int num2) { return (num1 + num2); }위와같은 함수는
 - 
        
template <typename T> T add(T num1, T num2) { return (num1 + num2); }이렇게 함수템플릿으로 선언할 수 있다.
 
 - 
        
 - 
    
template <typename T>대신,template <class T>로도 선언할 수 있다. - 실제로 위 함수가 사용되는 예시는 아래와 같다.
    
int main(void) { cout<<Add<int>(15, 20) <<endl; cout<<Add<double>(2.9, 3.7) <<endl; cout<<Add<int>(3, 3) <<endl; cout<<Add<double>(3.14, 2.75) <<endl; return (0); } - 함수 호출 시, 함수와 매개변수 사이에 
<변환될 자료형>을 넣어줄수도 있다. - 넣지않는다면, 컴파일러가 자료형으로 알아서 변환한다.
 - 컴파일러가 자료형으로 만드는 함수를 
템플릿 함수라고한다. - 또는, 
생성된 함수라고도 불린다. 
둘 이상의 형에 대해 템플릿 선언
- 템플릿의 정의에 다양한 자료형도 선언할 수 있다.
 - 둘 이상의 형에 대해서 템플릿을 선언할 수 있다.
 
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;
}
함수 템플릿의 특수화
- 템플릿 함수를 상황에따라 다르게 구성해야할수도 있다.
 - 단순히 크기 비교가 아닌, 문자열의 길이를 비교한다던지,
 - 사전편찬 순으로 비교한다던지를 하기위해서는 
함수 템플릿 특수화를 해야한다. 
template<>
char *Max<char *>(char *a, char *b)
{
	return (strlen(a) > strlen(b) ? a : b)
}
template<>
const char *Max<const char *>(const char *a, const char *b)
{
	return (strcmp(a, b)> 0 ? a : b);
}
- 컴파일러에게 특수화할 자료형의 함수를 전달해 해당 자료형의 경우에는 정의한 함수를 사용하도록한다.
 
클래스 템플릿
- 함수를 템플릿으로 정의했듯, 클래스도 템플릿으로 정의할 수 있다.
 - 이렇게 정의된 템플릿을 
클래스 템플릿, 이를 바탕으로 만들어진 클래스를템플릿 클래스라고한다. 
클래스 템플릿의 정의
- 저장하는 멤버변수가 다르다는 이유만으로 유사한 클래스를 여러개 정의하는 것은 비효율적이다.
 - 
    
이때 사용되는게 클래스 템플릿이다.
 - 정수형 좌표를 저장하는 클래스 예시
    
class Point { private : int x; int y; public: Point(int x, int y) : x(x), y(y) {} void ShowPosition() const { ... } }; 
내부 멤버변수가 float, char * 등등인 경우에 클래스를 각각 생성하는건 비효율적이다.
이때, 클래스 템플릿을 사용한다.
template <typename T>
class Point
{
	private:
		T x;
		T y;
	public:
		Point(T x, T y) : x(x), y(y)
		void ShowPosition() const
		{
			...
		}
};
- 컴파일러는 클래스 템플릿을 기반으로 템플릿 클래스를 만들어낸다.
 - 필요한 템플릿 클래스를 만들어서 객체를 생성해낸다.
 단, 클래스 템플릿은 반드시 객체생성시 자료형을 명시해야한다.
클래스 템플릿의 몸체 분리
- 위의 Point 클래스 템플릿의 몸체를 분리해보자.
 
template <typename T>
class Point
{
	private:
		T x;
		T y;
	public:
		Point(T x, T y);
		void ShowPosition() const;
};
template <typename T>
Point<T>::Point(T x, T y) : x(x), y(y)
{}
template <typename T>
void Point<T>::ShowPosition() const
{
	...
}
- 함수의 몸체에도 template을 선언해주어야 컴파일러가 잘 인식한다.
 
클래스 템플릿으로 템플릿 클래스의 객체를 담는 객체 생성
- 클래스 템플릿을 정의하면 어느 자료형이든 받을 수 있다.
 - 이에는 다른 클래스 템플릿으로 정의되어 생성된 템플릿 클래스도 담길 수 있다.
 
BoundCheckArray<int> iarr[50]; //int형 자료형을 담을 수 있다.
BoundCheckArray<Point<int>> parr[50]; //Point<int> 템플릿 클래스의 객체도 담을 수 있다.
BoundCheckArray<Point<int>*> ㅐparr[50]; //Point<int> 템플릿 클래스의 객체의 포인터도 담을 수 있다.
클래스 템플릿의 특수화
- 함수템플릿을 특수화했듯, 클래스 템플릿도 특수화할 수 있다.
 자료형에따라 다른 행동양식을 정하기 위해서사용한다.
template <typename T>
class A
{};
이런 클래스 템플릿에 대한 int 자료형에 대한 특수화는
template <>
class A<int>
{};
이렇게 할 수 있고, 객체를 생성하기 위해선
A<int> obj1;
으로 선언할 수 있다.
템플릿클래스 객체선언
- 
    
클래스 템플릿을 기반으로한 템플릿 클래스의 객체 선언방법
- 저장대상이 
tc<int>일 경우A<tc<int>> obj; - 저장대상이 
tc<int>*일 경우A<tc<int> *> obj; 
 - 저장대상이 
 
댓글남기기