템플릿

sz L·2023년 3월 31일
0

C++

목록 보기
30/40
post-thumbnail

템플릿은 "모형자"라고 생각하면 된다. 모형자는 모형을 그릴 때 사용되는데 빨간색 펜으로 그리면 빨간색 모형, 파란색으로 그리면 파란색 모형이 되는데 템플릿도 이와 유사하다.
.. '틀'이라고 이해

함수 템플릿

함수를 만드는 도구

  • 함수의 자료형이 결정되지 않았음
  • 함수의 기능
  • template 키워드 대신 class도 가능
  • 한 번 만들어진 함수는 자료형당 하나씩만 만들어짐
  • 함수는 컴파일 할 때 만들어짐(실행속도 감소X)
#include <iostream>
using namespace std;

template <typename T>
T Add(T num1, T num2)
{
	return num1 + num2;
}

int main()
{
	cout << Add<int>(15, 20) << endl;
	cout << Add<double>(2.9,3.7) << endl;
	cout << Add<int>(3.2,3.2) << endl;
	cout << Add<double>(3.14,2.75) << endl;

	return 0;
}


함수 템플릿과 템플릿 함수

함수 템플릿은 '함수를 만드는데 사용되는 템플릿'이고
템플릿 함수는 '템플릿을 기반으로 만들어진 함수'이다(호출 가능).

#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()
{
	cout << Add(5, 7) << endl;
	cout << endl;
	cout << Add(3.7,7.5) << endl;
	cout << endl;
	cout << Add<int>(5, 7) << endl;
	cout << endl;
	cout << Add<double>(3.7, 7.5) << endl;

	return 0;
}


둘 이상의 형(type)에 대한 템플릿 선언

#include <iostream>
using namespace std;

template <class T1,class T2>
void ShowData(double num)
{
	cout << (T1)num << ", " << (T2)num << endl;
}

int main()
{
	ShowData<char, int>(65);
	ShowData<char, int>(67);
	ShowData<char, double>(68.7);
	ShowData<short, double>(69.2);
	ShowData<short, double>(65);

	return 0;
}


함수 템플릿의 특수화

모든 타입에 사용가능한 템플릿 외에 특별한 타입에 대해서만 정의를 새롭게 하고싶을 때 사용한다

#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;
}

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

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

	return 0;
}


클래스 템플릿

  • 함수 호출 시 자료형 정보 생략 불가능 함
#include <iostream>
using namespace std;

template <typename T>
class Point
{
private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0);
	void ShowPosition() const;
};

template <typename T>
Point<T>::Point(T x,T y) : xpos(x), ypos(y)
{ }
template <typename T>
void Point<T>::ShowPosition() const
{
	cout << "[" << xpos << ", " << ypos << "]" << endl;
}

int main()
{
	Point<int> pos1(3, 4);
	pos1.ShowPosition();

	Point<double> pos2(2.4, 3.6);
	pos2.ShowPosition();

	Point<char> pos3('P', 'F');
	pos3.ShowPosition();

	return 0;
}


클래스 템플릿의 특수화

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

template <typename T>
class Point
{
private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0);
	void ShowPosition() const;
};
	
template <typename T>
Point<T>::Point(T x,T y) : xpos(x), ypos(y)
{ }
template <typename T>
void Point<T>::ShowPosition() const
{
	cout << "[" << xpos << ", " << ypos << "]" << endl;
}
	
template <typename T>
class SimpleDataWrapper
{
private:
	T mdata;
public:
	SimpleDataWrapper(T data) : mdata(data)
	{ }
	void ShowDataInfo()
	{
		cout << "Data: " << mdata << endl;
	}
};

template <>
class SimpleDataWrapper<char*>
{
private:
	char* mdata;
public:
	SimpleDataWrapper(char* data)
	{
		mdata = new char[strlen(data) + 1];
		strcpy(mdata, data);
	}
	void ShowDataInfo()
	{
		cout << "String: " << mdata << endl;
		cout << "Length: " << strlen(mdata) << endl;
	}
	~SimpleDataWrapper() { delete[] mdata; }
};

template <>
class SimpleDataWrapper <Point<int>>
{
private:
	Point<int> mdata;
public:
	SimpleDataWrapper(int x,int y):mdata(x,y)
	{ }
	void ShowDataInfo()
	{
		mdata.ShowPosition();
	}
};

int main()
{
	SimpleDataWrapper<int> iwrap(170);
	iwrap.ShowDataInfo();
	SimpleDataWrapper<char*> swrap("Class Template Specialization");
	swrap.ShowDataInfo();
	SimpleDataWrapper<Point<int>> poswrap(3, 7);
	poswrap.ShowDataInfo();
	
	return 0;
}

profile
가랑비는 맞는다 하지만 폭풍은 내 것이야

0개의 댓글