Understanding the C++ Templates
Learn how the templates work for various data types.
We'll cover the following...
The “empty stack” error in C++
When we attempt to pop an element from an empty stack without proper checking, we might face an error or exception called an “empty stack” error. The following code snippet gives us a more robust stack data structure where we remove all the elements and catch the Stack<>::pop(): empty stack
exception message.
#include <iostream>#include <string>#include <vector>#include <stdexcept>using namespace std;//We will define the Stack<> class and implement generic methods//to push and pop the elements from the stacktemplate <class T>class Stack {private:vector<T> elementsToPushAndPop;public:void push(T const&);void pop();T top() const;bool empty() const {return elementsToPushAndPop.empty();}};template <class T>void Stack<T>::push (T const& elem) {// we can append the copy of the element that we passedelementsToPushAndPop.push_back(elem);}template <class T>void Stack<T>::pop () {// if the stack is empty, we can throw an exceptionif (elementsToPushAndPop.empty()) {throw out_of_range("Stack<>::pop(): empty stack");}// then we can remove the last elementelementsToPushAndPop.pop_back();}template <class T>T Stack<T>::top () const {// if the stack is empty, we can throw an exceptionif (elementsToPushAndPop.empty()) {throw out_of_range("Stack<>::top(): empty stack");}// then we can return a copy of the last elementreturn elementsToPushAndPop.back();}int main(){// Let's create a stack of integer elementsStack<int> stackIntegers;// now we can keep adding to the stackstackIntegers.push(500);stackIntegers.push(501);cout << stackIntegers.top() << endl;if(stackIntegers.empty()){cout << "The stack is empty." << endl;} else {cout << "The stack is not empty." << endl;}// Let's remove one element from our stackstackIntegers.pop();// and see the outputcout << stackIntegers.top() << endl;// after that we can check whether the stack is emptyif(stackIntegers.empty()){cout << "The stack is empty." << endl;} else {cout << "The stack is not empty." << endl;}// and see the outputcout << stackIntegers.top() << endl;// Let's keep removing the stack elementstry {// this removes 500stackIntegers.pop();// if we try to remove the element again, it will throw an exception// that we can now catchstackIntegers.pop();} catch (exception const& excep) {cerr << "Exception: " << excep.what() << endl;return -1;}return 0;}
After we look at the output, we’ll see why we need to know how to create general template classes and generic methods. Here’s the output:
501
The stack is not empty.
500
The stack is not empty.
500
Exception: Stack<>::pop(): empty stack
-
Lines 9–46 The code above implements a generic stack class (
Stack<T>
) using a vector to store elements. The stack supports the following operations:push()
,pop()
,top()
, andempty()
. -
Line 50: In the
main()
function, astackIntegers
named instance of theStack<int>
class is created. -
Lines 53 and 54: Integer elements (
500
and501
...