An introduction to using template classes in C++, that starts extremely simply and builds up from there…
Example 1
Consider the following simple class that we use to store and print an integer:
#include <iostream> class A { private: int data; public: A( const int& d ); int Value() const; void Print() const; }; A::A( const int& d ) { data = d; } int A::Value() const {an return data; } void A::Print() const { std::cout << data << std::endl; } int main() { A a( 5 ); a.Print(); }
Now suppose we wish to do this in a generic way, allowing us to store and print not only integers, but any kind of primitive data type. The equivalent template class for class A would now look like this:
#include <iostream> template< class T> class A { private: T data; public: A( const T& d ); T& Value() const; void Print() const; }; template<class T> A<T>::A( const T& d ) { data = d; } template<class T> T& A<T>::Value() const { return data; } template<class T> void A<T>::Print() const { std::cout << data << std::endl; } int main() { A<int> a( 5 ); a.Print(); return 0; }
Example 2
In this example class A is used to maintain a std::vector
of generic data types, with functions to add to the vector set and print their contents:
#include <iostream> #include <vector>#include#include template class Queue { private: std::vector data; public: void push(T const &); void pop(); T front() const; void Print(); }; template void Queue ::push(T const &d) { data.push_back(d); } template void Queue ::pop() { data.erase(data.begin( ) + 0,data.begin( ) + 1); } template T Queue ::front() const { if ( data.size() > 0 ) { return *(data.begin()); } else { std::cerr << "Empty Queue. Returning garbage value\n"; T* temp = new(T); T garbage = * temp; delete temp; return garbage; } } template void Queue ::Print() { for ( int i = 0; i < (int) data.size(); i++ ) { T val = *( data.begin() + i ); std::cout << val << std::endl; } } int main() { Queue q; q.push(1); q.push(2); std::cout << q.front() << std::endl; std::cout << "Before removing data" << std::endl; q.Print(); q.pop(); std::cout << "After removing data"<< std::endl; q.Print(); return 0; } #include <string> template< class T> class A { private: std::vector<T> v; public: void Add( const T& d ); T& Value(const int& index) const; void Print() const; }; template<class T> void A<T>::Add( const T& d ) { v.push_back(d); } template<class T> T& A<T>::Value(const int& index) const { T val = 0; if (index < v.size() ) { val = v[ index ]; } return val; } template<class T> void A<T>::Print() const { for ( int i = 0; i < (int) v.size(); i++ ) { T val = *( v.begin() + i ); std::cout << val << std::endl; } } int main() { A<int>* a1 = new A<int>(); a1->Add( 4 ); a1->Add( 5 ); a1->Print(); delete a1; A<std::string> a2; a2.Add( "Hello" ); a2.Add( "World" ); a2.Print(); return 0; }
Example 3
This example uses a template function for finding the maximum of two generic data types:
#include <ostream> #include <vector> #include <string> const int& Max( const int& a, const int& b ) { return a > b ? a : b; } template<class T> inline const T& Max1( const T& a, const T& b ) { return a > b ? a : b; } int main() { int max = Max( 5, 55 ); std::cout << max << std::endl; double maxd = Max1( 23.3, 101.23 ); std::cout << maxd << std::endl; float maxf = Max1( 23.2, 111.1 ); std::cout << maxf << std::endl; return 0; }
Example 4
An example of using template classes in a queue, to store generic data types:
#include <iostream> #include <vector> template <class T> class Queue { private: std::vector<T> data; public: void push(T const &); void pop(); T front() const; void Print(); }; template <typename T> void Queue<T> ::push(T const &d) { data.push_back(d); } template <typename T> void Queue<T>::pop() { data.erase(data.begin( ) + 0,data.begin( ) + 1); } template <typename T> T Queue<T>::front() const { if ( data.size() > 0 ) { return *(data.begin()); } else { std::cerr << "Empty Queue. Returning garbage value\n"; T* temp = new(T); T garbage = * temp; delete temp; return garbage; } } template <typename T> void Queue<T>::Print() { for ( int i = 0; i < (int) data.size(); i++ ) { T val = *( data.begin() + i ); std::cout << val << std::endl; } } int main() { Queue<int> q; q.push(1); q.push(2); std::cout << q.front() << std::endl; std::cout << "Before removing data" << std::endl; q.Print(); q.pop(); std::cout << "After removing data"<< std::endl; q.Print(); return 0; }