Template C++ Tutorial

/* The following code example is taken from the book
 * "C++ Templates - The Complete Guide"
 * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
 *
 * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include 
#include 
#include 
#include 
#include 
#include 
template 
class Stack {
  private:
    std::vector elems;     // elements
  public:
    void push(T const&);      // push element
    void pop();               // pop element
    T top() const;            // return top element
    bool empty() const {      // return whether the stack is empty
        return elems.empty();
    }
};
template 
void Stack::push (T const& elem)
{
    elems.push_back(elem);    // append copy of passed elem
}
template
void Stack::pop ()
{
    if (elems.empty()) {
        throw std::out_of_range("Stack<>::pop(): empty stack");
    }
    elems.pop_back();         // remove last element
}
template 
T Stack::top () const
{
    if (elems.empty()) {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
    return elems.back();      // return copy of last element
}
template<>
class Stack {
  private:
    std::deque elems;  // elements
  public:
    void push(std::string const&);  // push element
    void pop();                     // pop element
    std::string top() const;        // return top element
    bool empty() const {            // return whether the stack is empty
        return elems.empty();
    }
};
void Stack::push (std::string const& elem)
{
    elems.push_back(elem);    // append copy of passed elem
}
void Stack::pop ()
{
    if (elems.empty()) {
        throw std::out_of_range
                ("Stack::pop(): empty stack");
    }
    elems.pop_back();         // remove last element
}
std::string Stack::top () const
{
    if (elems.empty()) {
        throw std::out_of_range
                ("Stack::top(): empty stack");
    }
    return elems.back();      // return copy of last element
}
int main()
{
    try {
        Stack         intStack;       // stack of ints
        Stack stringStack;    // stack of strings
        // manipulate int stack
        intStack.push(7);
        std::cout << intStack.top() << std::endl;
        intStack.pop();
        // manipulate string stack
        stringStack.push("hello");
        std::cout << stringStack.top() << std::endl;
        stringStack.pop();
    }
    catch (std::exception const& ex) {
        std::cerr << "Exception: " << ex.what() << std::endl;
        return EXIT_FAILURE;  // exit program with ERROR status
    }
}
7
hello
Exception: Stack::pop(): empty stack