템플릿 코드는 컴파일시에 채워진다.
각각 다른 데이터 타입으로 적절하게 컴파일러가 변환시켜준다.
오버로딩과는 다른 점은 한 템플릿을 만들면 여러가지 타입에 맞게 쓸 수 있다는 점이다.
하지만 오류가 자주 일어날 수 있다.
또는 템플릿 적용이 안될때도 있음. 타입이 안맞던가 해서..
그럴 때는 따로 함수를 만들거나 구체화 시키면된다.
template<class T1, class T2>
double add(T1 num1, T2 num2) {
return num1 + num2;
}
void main() {
cout << add(2, 3) << endl;
cout << add(2.1, 2.1) << endl;
cout << add(1, 1.3) << endl;
}
5
4.2
2.3
저런 식으로 사용하면된다.
사실 저 코드는 리턴 타입 뭐 쓸지 애매하긴하다.
template<class T1, class T2>
double add(T1 num1, T2 num2) {
return num1 + num2;
}
template<class T>
T add(T num1, T num2) {
return num1 + num2;
}
void main() {
cout << add(2, 3) << endl;
cout << add(2.1, 2.1) << endl;
cout << add(1, 1.3) << endl;
}
이럴 경우에는 밑에 마지막 식만 맨 위의 템플릿에 들어가게 된다.
컴파일러가 자동으로 적절한 템플릿을 호출해준다.
함수 템플릿과 유사하게 사용된다. 각 데이터 타입마다 클래스가 만들어진다.
데이터 타입 T는 클래스 내부에서 어디든지 사용가능하다.
template<class T>
class Array {
private:
T* ptr = nullptr;
int size = 0;
public:
Array(int size) :size(size) {
ptr = new T[size];
}
int getSize() const {
return size * sizeof(T);
}
~Array() {
delete[]ptr;
}
};
void main() {
Array<int> a1{ 5 };
cout << a1.getSize() << endl;
Array<double> a2{ 5 };
cout << a2.getSize() << endl;
}
20
40
여기서 주의할 점은 클래스내에서 T의 사용하는 방법과 클래스를 호출할 때 타입을 지정해줘야한다는 점이다.
template<class T,int size>로 설정해서 값을 받을 수도 있다. default값도 가능
함수면 인자로 받으면 된당.
template<class T,int size>
class Array {
private:
T* ptr = nullptr;
public:
Array(){
ptr = new T[size];
}
int getSize() const {
return size * sizeof(T);
}
~Array() {
delete[]ptr;
}
};
void main() {
Array<int, 5> a1;
cout << a1.getSize() << endl;
}
template<class T>
T add(T a, T b) {
return a + b;
}
template<>
const char* add(const char* a, const char* b) {
return "char*";
}
void main() {
cout << add(1, 2) << endl;
cout << add("a", "b") << endl;
}
3
char*
이렇게 구체화 시켜줘야하는 이유는 단순히 한 템플릿으로 해결되지 않아서이다.
문자열을 합치고 싶다면 strcpy를 써서 하나의 변수를 만들어라
template<class T>
class MyData {
private:
T data;
public:
MyData(T value) :data{ value } {}
T getData() const {
return data;
}
};
template<>
class MyData<char*> {
private:
char* data;
public:
MyData(const char* value) :data(new char[strlen(value) + 1]) {
strcpy_s(data, strlen(value) + 1, value);
}
const char* getData() const {
return data;
}
~MyData() {
delete[]data;
}
};
void main() {
cout << MyData{ 5 }.getData() << endl;
cout << MyData<char*>{"dlwlrma"}.getData() << endl;
}
5
dlwlrma
c++17부터 저렇게 식을 쓸 수 있지만 굳이라는 생각이 든다.
Prac 1
int sum;
int intsum;
template<class T>
T* mem(int a) {
T* tmp = new T[a];
sum += sizeof(T) * a;
return tmp;
}
template<>
int* mem(int a) {
int* tmp = new int[a];
sum += sizeof(int) * a;
intsum = sizeof(int) * a;
return tmp;
}
int main() {
char* cdata;
int* idata;
double* ddata;
cdata = mem<char>(2);
idata = mem<int>(2);
ddata = mem<double>(3);
cout << "global memeory footprint : " << sum << endl;
cout << "int memory footprint : " << intsum << endl;
delete[]cdata;
delete[]idata;
delete[]ddata;
return 0;
}
global memeory footprint : 34
int memory footprint : 8