Class Templates
Class template는 코드를 재사용하기 위한 또다른 수단이다. C++의 STL(Standard Template Library)는 valarray, vector, array와 같은 여러 temlate class들을 지원한다. 이렇게 type-independent한 형태로 코드를 작성하는 패러다임을 generic programming이라고 부른다.
Defining a Class Template
Class template의 정의는 function template과 유사하다. 개발자와 compiler가 찾기 쉬운(ex, header file) 곳에 정의할 필요가 있다.
Stack을 class template을 사용하여 구현해보자.
template <typename Type> // Type : type parameter
// equivalent with
// template <class Type>
class Stack
{
private:
enum {MAX = 10}; // constant specific to class
Type items[MAX]; // holds stack items
int top; // index for top stack item
public:
Stack();
bool isempty();
bool isfull();
bool push(const Type& item);
bool pop(Type& item);
};
template<typename Type>
Stack<Type>::Stack()
{
top = 0;
}
여기서 type parameter(Type)은 매개변수처럼 원하는 type을 컴파일러에게 넘긴다. function template의 경우, 넘겨받은 값의 type에 맞게 맞춰지지만 class template은 type을 명시해줘야 한다.
Stack<int> kernels; // create a stack of ints
Stack<string> colonels; // create a stack of string objects
template<class T> void simple(T t) { cout << t << ‘\n’; }
simple(2); // generate void simple(int)
simple(“two”); // generate void simple(const char*)
일단 stack이 특정한 type으로 생성이 된다면, 해당 type의 ordinary object로 사용할 수 있다.
Non-Type Arguments
Array temlate을 예시로 Non-Type argument를 어떻게 받을 수 있는지 살펴보겠다.
template <class T, int n> // Type argument: T, argument: n
class ArrayTP
{
private:
T ar[n];
public:
ArrayTP() {}
explicit ArrayTP(const T& v);
virtual ~ArrayTP() {}
virtual T& operator[](int i);
virtual T operator[](int i) const;
};
template<class T, int n>
ArrayTP<T,n>::ArrayTP(const T& v)
{
for(int i = 0; i < n; i++)
ar[i] = v;
}
ArrayTP<double, 12> eggweights;
위 코드에서 컴파일러는 double eggweights[12]와 동일하게 대체한다. 이때, integer parameter(n)은 반드시 컴파일 타임에 결정되는 상수여야 한다. 상수이기만 한다면 integer type, enumeration type, reference, pointer 무엇이든 상관 없다. 그러나 altered value나 address를 받을 수는 없다(n++, &n). 이를 non-type 혹은 expression argument라고도 부른다.
Template Versatility
Using More Than One Type Parameter
Default Type Template Parameters
Explicit Specializations
template<class T> class Test
{
public:
Test() { cout << "General template object\n"; }
};
template<> class Test<int>
{
public:
Test() { cout << "Specialized template object for int\n"; }
};
int main()
{
Test<int> a; // Specialized template object for int
Test<char> b; // General template object
Test<float> c; // General template object
return 0;
}
Partial Specialization
Member Templates
C++에서 class 안에 class를 정의할 수 있다. 마찬가지로, template class 안에도 template class와 template function을 정의할 수 있다.
template<typename T>
class A {
private:
template<typename V>
class B { ... };
B<int> q;
B<T> m;
template<typename U> U func(U a, T b) { ... }
// ...
};
Template Aliases
Questions?
Q1.
A1.
Q2.
A2.
[students]: