C++에서 template를 사용하는 방법 중, 자료 형 이 아닌 매개변수를 template로 사용하는 방법이 있다.
#include <iostream>
using namespace std;
// 자료형이 아닌 매개변수를 받아오는 템플릿
template<typename T, unsigned int SIZE>
class MyArray
{
public:
MyArray() = default;
~MyArray() {}
T& operator[](int index) {
return arr2[index];
}
private:
T arr1[10]; // 상수만 들어가면서 형태만 띄고있는것.
T arr2[SIZE];
};
int main()
{
MyArray<int, 30> arr1;
MyArray<float, 30u> arr2;
for (int i = 0; i < 30; i++)
arr1[i] = i;
for (int i = 0; i < 30; i++)
arr2[i] = i;
for (int i = 0; i < 30; i++)
cout << arr1[i] << ' ';
std::cout << std::endl;
for (int i = 0; i < 30; i++)
cout << arr2[i] << ' ';
std::cout << std::endl;
return 0;
}
template 특수화
특정 자료형에 대해 virtual 처리 또는 함수 오버로딩 처리 하여 특정상황 에서만 동작하게 하는것.
#include <iostream>
using namespace std;
// 템플릿 특수화
// 템플릿은 어떠한 자료형이 들어가든 동작하도록 넣는건데,
// 특정한 자료형에 대해 예외처리를 하기 위해 만들어지는 것.
template<typename T>
T GetMax(T x, T y)
{
return (x > y) ? x : y;
}
template<>
char GetMax(char x, char y)
{
cout << "Warning : comparing chars" << endl;
return (x > y) ? x : y;
}
template<class T>
class Storage
{
T value;
public:
Storage(T value)
:value(value)
{}
void Print()
{
cout << value << endl;
}
};
// 이와 같은 경우로 template 또한 다형성의 형태 중 하나임 을 알 수 있다.
template <>
void Storage<double>::Print()
{
cout << "double : " << value << endl;
}
int main()
{
cout << GetMax<int>(1, 2) << endl;
cout << GetMax<float>(1.1f, 2.2f) << endl;
cout << GetMax<char>(1, 2) << endl;
cout << GetMax('a', 'b') << endl;
Storage<int> s1(5);
s1.Print();
Storage<double> s2(5.5);
s2.Print();
return 0;
}
Class Template
함수 클래스 자체 전체를 특수화 하여, 탬플릿으로 만드는것.
#include<iostream>
using namespace std;
// 클래스 자체, 전체의 특수화 이다.
template<class T>
class A
{
public:
A(const T& input) {}
void DoSomthing()
{
cout << typeid(T).name() << endl;
}
void Test() {}
};
// class 자체를 특수화 하였을 때. 매개함수를 바꾸어줄 수 있다.
template<>
class A<char>
{
public:
A(const char& input) {}
void DoSomthing()
{
cout << "char type specialization" << endl;
}
};
int main()
{
A<int> aint(10);
A<double> adouble(10.1);
A<char> achar('a');
aint.DoSomthing();
adouble.DoSomthing();
achar.DoSomthing();
aint.Test();
adouble.Test();
//achar.Test(); achar에는 Test 인수가 없다.
return 0;
}
일반 함수, 클래스 맴버함수 특수화
#include<iostream>
using namespace std;
// 부분만 특수화 시키고 싶을 때 사용한다.
// 함수에 대한 부분 특수화를 진행한다.
#pragma region 1.일반 함수 부분 특수화
//template<class T, int size>
//class StaticArray
//{
// T arr[size];
//
//public:
// T* GetArray() { return arr; }
//
// T& operator[](int index)
// {
// return arr[index];
// }
//
// void Print1()
// {
// for (int i = 0; i < size; i++)
// {
// cout << (*this)[i] << ' ';
// }
// cout << endl;
// }
//};
//
//template<typename T, int size>
//void Print2(StaticArray<T, size>& arr)
//{
// for (int i = 0; i < size; i++)
// {
// cout << arr[i] << ' ';
// }
// cout << endl;
//}
//
//template<int size>
//void Print2(StaticArray<char, size>& arr)
//{
// for (int i = 0; i < size; i++)
// {
// cout << arr[i];
// }
// cout << endl;
//}
#pragma endregion
#pragma region 2.클래스 멤버 함수 부분 특수화
template<class T, int size>
class StaticArray_Base
{
T arr[size];
public:
T* GetArray() { return arr; }
T& operator[](int index)
{
return arr[index];
}
virtual void Print1()
{
for (int i = 0; i < size; i++)
{
cout << (*this)[i] << ' ';
}
cout << endl;
}
};
template<class T, int size>
class StaticArray : public StaticArray_Base<T, size>
{
};
template<int size>
class StaticArray<char, size> : public StaticArray_Base<char, size>
{
public:
void Print1() override
{
for (int i = 0; i < size; i++)
{
cout << (*this)[i];
}
cout << endl;
}
};
#pragma endregion
int main()
{
StaticArray<int, 4> int4;
int4[0] = 1;
int4[1] = 2;
int4[2] = 3;
int4[3] = 4;
int4.Print1();
//Print2(int4);
StaticArray<char, 6> char6;
char6[0] = 'H';
char6[1] = 'E';
char6[2] = 'L';
char6[3] = 'L';
char6[4] = 'O';
char6[5] = '\n';
char6.Print1();
//Print2(char6);
return 0;
}
Class 포인터 에 대한 특수화
#include <iostream>
using namespace std;
template<class T>
class A
{
T value;
public:
A(const T& value) : value(value) {}
void Print()
{
cout << value << endl;
}
};
template<class T>
class A<T*>
{
T* value;
public:
A(T* value) : value(value) {}
void Print()
{
cout << *value << endl;
}
};
int main()
{
A<int> Aint(123);
Aint.Print();
int temp = 456;
A<int*> Aptr(&temp);
Aptr.Print();
return 0;
}
'서울게임아카데미 교육과정 6개월 C++ ~ DirectX2D' 카테고리의 다른 글
42일차. 오답정리 확인 (0) | 2023.06.09 |
---|---|
41일차. 오답정리 (0) | 2023.06.06 |
39일차 Template 01_function_template, 02_class_template (0) | 2023.05.31 |
38일차 01_STL (0) | 2023.05.28 |
37일차 15.pure_virtual_function_and_astract_class 16.virtual_base_class_and_the_diamond_prolem 17.dynamic_casting (0) | 2023.05.25 |