The following example uses a stack to demonstrate a general, template-based data structure. But it isn't the first example based on a stack. Previously, we've studied automatic and dynamic stack implementations. And most recently, we used a stack class to illustrate The "this" Pointer. For brevity, the current example focuses only on the automatic implementation, but it presents two versions.
Sets a fixed stack size, wasting space if the size is much larger than needed, or failing if the size is too small.
Allows the user to specify the stack size through a template variable. Specifying a default size, = 100, is optional.
Fixed Size
Template Variable Size
template <class T>
class stack
{
private:
static const int SIZE = 100;
T st[SIZE];
int sp;
template <class T, int SIZE = 100>
class stack
{
private:
T st[SIZE];
int sp = 0;
(a)
(b)
template <class T>
T stack<T>::pop()
template <class T, int SIZE>
T stack<T, SIZE>::pop()
(c)
(d)
Fixed size stack vs. a variable sized stack. There is little difference between the two versions. There are some minor differences between the classes and the function headers, but the function bodies are the same. The differences are highlighted here.
A partial stack class. The yellow-highlighted syntax makes stack a template class. The blue-highlighted statement creates a class-scope symbolic constant that fixes the stack size at 100 elements.
Another partial stack class, but this version adds a template variable with a default value (in red). The template variable allows an application programmer to specify the stack size with a template argument. If we omit the default value, the application programmer must provide a stack size. Figure 3 illustrates how to accept or override the default stack size.
The "boilerplate" syntax used to introduce each stack function when there is only a type template variable.
The "boilerplate" syntax used to introduce each stack function when there are two template variables - one for the generalized class and another for the size of the stack.