14. 템플릿(Template) 2
출처: 윤성우 열혈강의 C++ 예제코드
14.1. Chapter 13에서 공부한 내용의 확장
- 특정 템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와 friend선언
#include <iostream>
using namespace std;
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0): xpos(x), ypos(y)
{ }
void ShowPosition() const
{
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
friend Point<int> operator+(const Point<int>&, const Point<int>&);
friend ostream& operator<<(ostream& os, const Point<int>& pos);
};
Point<int> operator+(const Point<int>& pos1, const Point<int>& pos2)
{
return Point<int>(pos1.xpos+pos2.xpos, pos1.ypos+pos2.ypos);
}
ostream& operator<<(ostream& os, const Point<int>& pos)
{
os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
return os;
}
int main(void)
{
Point<int> pos1(2, 4);
Point<int> pos2(4, 8);
Point<int> pos3=pos1+pos2;
cout<<pos1<<pos2<<pos3;
return 0;
}
14.2. 클래스 템플릿의 특수화(Class Temlpate Specialization)
- 클래스 템플릿 특수화 하기(template parameter 전체)
#include <iostream>
#include <cstring>
using namespace std;
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0): xpos(x), ypos(y)
{ }
void ShowPosition() const
{
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
};
template <typename T>
class SimpleDataWrapper
{
private:
T mdata;
public:
SimpleDataWrapper(T data) : mdata(data)
{ }
void ShowDataInfo(void)
{
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(void)
{
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(void)
{
mdata.ShowPosition();
}
};
int main(void)
{
SimpleDataWrapper<int> iwrap(170);
iwrap.ShowDataInfo();
SimpleDataWrapper<char*> swrap("Class Template Specialization");
swrap.ShowDataInfo();
SimpleDataWrapper<Point<int>> poswrap(3, 7);
poswrap.ShowDataInfo();
return 0;
}
- 클래스 템플릿 특수화 하기(template parameter 일부)
#include <iostream>
using namespace std;
template <typename T1, typename T2>
class MySimple
{
public:
void WhoAreYou()
{
cout<<"size of T1: "<<sizeof(T1)<<endl;
cout<<"size of T2: "<<sizeof(T2)<<endl;
cout<<"<typename T1, typename T2>"<<endl;
}
};
template<>
class MySimple<int, double>
{
public:
void WhoAreYou()
{
cout<<"size of int: "<<sizeof(int)<<endl;
cout<<"size of double: "<<sizeof(double)<<endl;
cout<<"<int, double>"<<endl;
}
};
template<typename T1>
class MySimple<T1, double>
{
public:
void WhoAreYou()
{
cout<<"size of T1: "<<sizeof(T1)<<endl;
cout<<"size of double: "<<sizeof(double)<<endl;
cout<<"<T1, double>"<<endl;
}
};
int main(void)
{
MySimple<char, double> obj1;
obj1.WhoAreYou();
MySimple<int, long> obj2;
obj2.WhoAreYou();
MySimple<int, double> obj3;
obj3.WhoAreYou();
return 0;
}
14.3. 템플릿의 인자
- 템플릿 매개변수에 변수 선언하기
#include <iostream>
using namespace std;
template <typename T, int len>
class SimpleArray
{
private:
T arr[len];
public:
T& operator[] (int idx)
{
return arr[idx];
}
T& operator=(const T&ref)
{
for(int i=0; i<len; i++)
arr[i]=ref.arr[i];
}
};
int main(void)
{
SimpleArray<int, 5> i5arr1;
for(int i=0; i<5; i++)
i5arr1[i]=i*10;
SimpleArray<int, 5> i5arr2;
i5arr2=i5arr1;
for(int i=0; i<5; i++)
cout<<i5arr2[i]<<", ";
cout<<endl;
SimpleArray<int, 7> i7arr1;
for(int i=0; i<7; i++)
i7arr1[i]=i*10;
SimpleArray<int, 7> i7arr2;
i7arr2=i7arr1;
for(int i=0; i<7; i++)
cout<<i7arr2[i]<<", ";
cout<<endl;
return 0;
}
- 템플릿 매개변수에 디폴트 값 지정하기
#include <iostream>
using namespace std;
template <typename T=int, int len=7>
class SimpleArray
{
private:
T arr[len];
public:
T& operator[] (int idx)
{
return arr[idx];
}
T& operator=(const T&ref)
{
for(int i=0; i<len; i++)
arr[i]=ref.arr[i];
}
};
int main(void)
{
SimpleArray<> arr;
for(int i=0; i<7; i++)
arr[i]=i+1;
for(int i=0; i<7; i++)
cout<<arr[i]<<" ";
cout<<endl;
return 0;
}
14.4. 템플릿과 static
- 함수 템플릿에 static 지역변수 사용하기
#include <iostream>
using namespace std;
template <typename T>
void ShowStaticValue(void)
{
static T num=0;
num+=1;
cout<<num<<" ";
}
int main(void)
{
ShowStaticValue<int>();
ShowStaticValue<int>();
ShowStaticValue<int>();
cout<<endl;
ShowStaticValue<long>();
ShowStaticValue<long>();
ShowStaticValue<long>();
cout<<endl;
ShowStaticValue<double>();
ShowStaticValue<double>();
ShowStaticValue<double>();
return 0;
}
1 2 3
1 2 3
1 2 3
- 클래스 템플릿에 static 지역변수 사용하기
#include <iostream>
using namespace std;
template <typename T>
class SimpleStaticMem
{
private:
static T mem;
public:
void AddMem(int num) { mem+=num; }
void ShowMem() { cout<<mem<<endl; }
} ;
template <typename T>
T SimpleStaticMem<T>::mem=0;
/*
template<>
long SimpleStaticMem<long>::mem=5;
*/
int main(void)
{
SimpleStaticMem<int> obj1;
SimpleStaticMem<int> obj2;
obj1.AddMem(2);
obj2.AddMem(3);
obj1.ShowMem();
SimpleStaticMem<long> obj3;
SimpleStaticMem<long> obj4;
obj3.AddMem(100);
obj4.ShowMem();
return 0 ;
}
5
100