1 / 23

C++ Templates

C++ Templates. Why Use Templates?. C++ requires variables, functions, classes etc with specific data types. However, many algorithms (quicksort for example) have almost the same code but with different data types. Why Use Templates?. Without templates one of the following options must be used:

johnmorton
Download Presentation

C++ Templates

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++ Templates

  2. Why Use Templates? C++ requires variables, functions, classes etc with specific data types. However, many algorithms (quicksort for example) have almost the same code but with different data types.

  3. Why Use Templates? Without templates one of the following options must be used: • Re-implement the algorithm with each data type. • Write general code using Object or void* • Using preprocessors

  4. Why Use Templates? • Re-implementing causes code duplication and can introduce errors. • Writing general code bypasses all type-checking. • Preprocessors replace text indiscriminately and can introduce errors by compiling code the programmer never even sees.

  5. Example Return the maximum of two parameters. int max(int a, int b) { return (a > b) ? a : b; } float max(float a, float b) { return (a > b) ? a : b; } double max(double a, double b) { return (a > b) ? a : b; } void* max(void *a, void *b) { return (*a > *b) ? a : b; } #define MAX(A,B) (a>b)?a:b;

  6. Example Instead, this function can be implemented using function templates. template <typename T> T max(T a, T b) { return (a > b) ? a : b; } The type used by this function is determined when it is called. int main() { cout << max(5,6) << endl; }

  7. Example For the compiler to match the type with the template, the type of both arguments must match. The following will cause an error: template <typename T> T max(T a, T b) { return (a > b) ? a : b; } int main() { cout << max(5,6.0) << endl; }

  8. Example This can be solved in several ways: template <typename T> T max(T a, T b) { return (a > b) ? a : b; } int main() { cout << max((double)5,6.0) << endl; cout << max<double>(5,6.0) << endl; } Or: template <typename T1, typename T2> T1 max(T1 a, T2 b) { return (a > b) ? a : b; }

  9. Example However, this causes a new problem. The return type is defined as the first type. int main() { cout << max(5,6.0) << endl; //is different to cout << max(6.0,5) << endl; }

  10. Overloading Function Templates Like other functions in C++, function templates can be overloaded. For example with a specific type. int max(int a, int b) { return (a > b) ? a : b; } template <typename T> T max(T a, T b) { return (a > b) ? a : b; } int main() { cout << max(5,6) << endl; //uses non-template cout << max(5.0,6.0) << endl; //uses template }

  11. Class Templates The next common use of templates is class templates. This is especially useful for container classes that are used to store objects. template <typename T> class Stack { private: std::vector<T> items; public: void push(T const&); void pop(); T top() const; bool empty() const { return items.empty();} };

  12. Class Templates Members functions need to be written with template information. template <typename T> void Stack<T>::push(T const &a) { items.push_back(a); } These classes can be used by defining the data type they will be used to store: int main() { Stack<int> intStack; Stack<float> floatStack; Stack<string> stringStack; }

  13. Class Templates Classes can be specialised for particular types. template <> class Stack<int> { private: vector<int> items; public: void push(int); void pop(); int top(); bool empty() const {return items.empty();} };

  14. Class Templates A class can also be partially specialised. template <typename T1, typename T2> class myClass{ ... }; template <typename T> class myClass<T, T>{ ... }; template <typename T> class myClass<T, int>{ ... }; template <typename T1, typename T2> class myClass<T1*, T2*>{ ... };

  15. Class Templates Or with default template arguments: template <typename T, typename CONT=vector<T> > class Stack { private: CONT items; public: void push(T const &); void pop(); T top() const; bool empty() const {items.empty();} }; int main() { Stack<int> vectorStack; //uses vector Stack<int, deque<int> > dequeStack; //uses deque }

  16. Nontype Template Parameters Template parameters don’t necessarily have to be types. These parameters can also be ordinary values: template <typename T, int MAXSIZE> class Stack { private: T items[MAXSIZE]; int numItems; public: Stack(); void push(T const &); void pop(); T top() const; bool empty() const; bool full() const; };

  17. Nontype Template Parameters This allows a Stack to be created with a specific type and size. int main() { Stack<int, 20> int20Stack; Stack<int, 40> int40Stack; } It is important to note that these two instances are of different types. Stack<int, 20> is a different type to Stack<int, 40>.

  18. Template Template Parameters A template parameter can also be a class template. This can be useful to avoid the following situations: template <typename T, typename CONT=vector<T> > class Stack { ... }; int main() { Stack<int> vectorStack; //uses vector Stack<int, deque<int> > dequeStack; //uses deque } Here the type of the Stack is defined twice. int and deque<int>

  19. Template Template Parameters A template parameter can also be a class template. This can be useful to avoid the following situations: template <typename T, typename CONT=vector<T> > class Stack { ... }; int main() { Stack<int> vectorStack; //uses vector Stack<int, deque<int> > dequeStack; //uses deque } Here the type of the Stack is defined twice. int and deque<int>

  20. Template Template Parameters It would be better to be able to define the stack as: int main() { Stack<int, vector> vectorStack; //uses vector Stack<int, deque> dequeStack; //uses deque } To do this we have to define the second parameter as a template template parameter. The following code defines this. template <typename T, template<typename ELEM> class CONT = vector > class Stack { ... };

  21. Template Template Parameters However, there is a problem with this. The std vector has more than one parameter. The second is the allocator. This must be defined in order to make the templates work: template <typename T, template<typename ELEM, typename ALLOC = allocator<ELEM> > class CONT = vector > class Stack { ... };

  22. Template Template Parameters All this templates code just so we can create a Stack using code like this: int main() { Stack<int, vector> vectorStack; Stack<int, deque> dequeStack; }

  23. Summary Function Templates Class Templates Parameterised Templates Type Parameters Nontype Parameters Template Template Parameters

More Related