Templates • 3 Templates and type parameters • The basic idea templates is simple: we can make code depend on parameters, so that it can be used in different situations by instantiating the parameters as needed. In C, as in practically all programming languages • most basic form of code that takes a parameter is a function. For example, • consider this C function: Cont.. • • • • • int square (int n ) { return n * n ; } Here the expression n * n has been made parametric in n. Hence we can apply • it to some integer, say square(42) Cont… • Templates take the idea of parameterizing code much further. In particular, the • parameters may be types. For example, if F is a C++ template, it could be • instantiated with int as the type, as in • F<int> • A typical example is the standard library template vector. By instantiating it • with int, as in vecor<int>, we get a vector of integers. Cont… • Note the fundamental difference to the function square above • In the function int is the type of the argument, • whereas in F<int>, the argument is int itself • There are two kinds of templates in C++: • 1. Class templates • 2. Function templates • These correspond roughly to polymorphic data types and polymorphic functions • in functional languages. Cont… • To first approximation, you can think of template instantiation as substitution of the formal parameters by the actual arguments. Suppose we have a template • template<typename T> • struct s { • ... T ... T ... • }; Cont… • Then instantiating the template with argument A replaces T with A in the template body That is, s<A> works much as if we had written a definition with the arguments filled in: • struct sA { • ... A ... A ... • }; Cont… • The reality is more complex, but details may depend on the c++ implementation. • A naive compiler may cause code bloat by creating and then compiling lots of template instantiations s<A>,s<A2>,s<A3>,…. It is an interesting question how an optimizing compiler and /or a careful template programmer may avoid this risk of potential code bloat. On the other hand, because the argument replacement happens at compile time, there is no more overhead at runtime. Templates can produce very efficient code, in keeping with the aim of C++ to provide “zero-overhead” abstractions. • In C a similar form of replacement of parameters could be attempted using the macro processor. Templates, however,are far more structured than macros, which should be avoided in C++. • We read template<typename T> as analogous to T. Function templates • Overloaded function normally perform similar or identical operations on different types of data. • If the operations are identical for each type, they can be expressed more compactly and conveniently using function templates. • All function-template begins with keyword template followed by a list of template parameters to the function template enclosed in angle brackets (< and >); Cont… • Each template parameter that represents a type must be preceded by either of the interchangeable keywords class or typename, as in • Template<typename T> • or • Template <class elementtype> • or • Template<typename Bordertype, typename filltype> Cont… • The type template parameters of a function-template definition are used to specify the types of the arguments to the function, to specify the return type of the function and to declare variables within the function. • Example: • Void printarray(const int *array, int count) • { for (int i=0; i<count; I++) Cout <<array[i]<<“”; cout <<endl; } Cont… • The name of a template parameter can be declared only once in the template parameter list of a template header ,but can be used repeatedly in function’s header and body. • Template parameter names among function templates need not be unique. • • • • • • • • • • • • • • • • Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one. Templates are very useful when implementing generic constructs like vectors, stacks, lists, queues which can be used with any arbitrary type C++ templates provide a way to re-use source code as opposed to inheritance and composition which provide a way to re-use object code. There are two kinds of templates: function templates and class templates Use function templates to write generic functions that can be used with arbitrary types. For example, one can write searching and sorting routines which can be used with any arbitrary type. The Standard Template Library generic algorithms have been implemented as function templates, and the containers have been implemented as class templates Function templates A function template behaves like a function except that the template can have arguments of many different types In other words; a function template represents a family of functions. The general format of a function template is as follows: template <class T> return type functionname(argument of type T ) { // body of function with Type T } The following example declares a function template max(x, y) which returns either x or y, whichever is larger template <class myType> myType max (myType a, myType b) { return (a>b?a:b);} The above definition of function max() can work with different kinds of data types. A function template does not occupy space in memory. The actual definition of a function template is generated when the function is called with a specific data type. The function template does not save memory. Class templates • Class templates are called parameterized types ,because they require one or more type parameters to specify how to customize a “generic class” template to form a classtemplate specialization. • Example: • Stack – a datastructure into which we insert items at the top and retrieve those items in last-in,first-out order) • One stack class template, become the bases for creating many stack classed (such as “stack of double,”stack of int,”stack of char,”stack of employee,”etc.) • Creating class template stack<T> Cont… • • • • • • #ifndef STACK_H #define STACK_H Template <typename T> Class Stack { Public: Stack(int=10);//default constructor (stack size 10) // destructor ~Stack() { delete[] stackPtr; //deallocate internal space for stack }// end ~stack destructor Cont… • Bool push(const T&);//push an element onto the stack • Bool pop(T&); //Pop an element off the stack • Bool isempty() const • { return top == -1; }//end function is empty //determine whether stack is full Cont… • Bool isfull() const • { return top==size-1; }//end function isfull Private; int size; //# of element in the stack int top;//location of the top element (-1 means empty) T *stackptr; //pointer to internal representation of the stack }; Cont… • //constructor template • Template<typename T> • Stack<T>::stack(int s) :Size(S>0?s:10),//validate size top(-1),//stack initially empty stackptr(new T[Size]) //allocate memory for elements { //empty body } //end stack constructor template Cont… • //push element onto stack; • //if successful, return true;otherwise,return false • Template<typename T> • Bool Stack <T>::push(const T &pushvalue) if (lisfull()) { stackPtr[ ++top ] = pushvalue://place item on stack Cont… return true; // pop successful } //endif return false; //push unsuccessful }//end function template push // pop element off stack; //if successful, return true; otherwise,return false Template<typename T> bool stack<T>::pop(T &popvalue) Cont… • { • if (!isEmpty() ) • { popvalue = stackptr [top--]; //remove item from stack return true; //pop successful } //end if Return false; // pop unsuccessful }//end function template pop #endif Cont… • • • • • Template<typename T, int elements> //non type parameter elements Stack<double, 100 > …… Templates and inheritance A class template can be derived from a class template specialization • A class template can be derived from a nontemplate class. • A class-template specialization can be derived from a class-templat Containers and templates • template<typename T, typename Container> • A container is a holder object that stores a collection of other objects (its elements). They are implemented as class templates, which allows a great flexibility in the types supported as elements. The container manages the storage space for its elements and provides member functions to access them, either directly or through iterators (reference objects with similar properties to pointers). Containers replicate structures very commonly used in programming: dynamic arrays (vector), queues (queue), stacks (stack), heaps (priority queue), linked lists (list), trees (set), associative arrays (map)... Cont… • Many containers have several member functions in common, and share functionalities. The decision of which type of container to use for a specific need does not generally depend only on the functionality offered by the container, but also on the efficiency of some of its members (complexity). This is especially true for sequence containers, which offer different trade-offs in complexity between inserting/removing elements and accessing them. stack, queue and priority queue are implemented as container adaptors. Container adaptors are not full container classes, but classes that provide a specific interface relying on an object of one of the container classes (such list) to handle the elements. The underlying container is encapsulated in such a way that its elements are accessed by the members of the container adaptor independently of the underlying container class used. Cont… • Container class templates • Sequence containers: arrray Array class (class template )vactorVector (class template ) Double ended queue (class template )forward list Forward list (class template ) list List (class template ) Cont… • Container adaptors: • stackLIFO stack (class template )queueFIFO queue (class template )priority_queuePriority queue (class template ) Associative containers: setSet (class template )multisetMultiple-key set (class template )mapMap (class template )multimapMultiple-key map (class template ) Unordered associative containers: unordered_set Unordered Set (class template )unordered_multiset Unordered Multiset (class template )unordered_map Unordered Map (class template )unordered_multimap Unordered Multimap (class template ) Revision • Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one. Templates are very useful when implementing generic constructs like vectors, stacks, lists, queues which can be used with any arbitrary type • C++ templates provide a way to re-use source code as opposed to inheritance and composition which provide a way to re-use object code. • There are two kinds of templates: function templates and class templates • Use function templates to write generic functions that can be used with arbitrary types. For example, one can write searching and sorting routines which can be used with any arbitrary type. The Standard Template Library generic algorithms have been implemented as function templates, and the containers have been implemented as class templates Cont… • • • • • • • • • • • • Function templates A function template behaves like a function except that the template can have arguments of many different types In other words; a function template represents a family of functions. The general format of a function template is as follows: template <class T> return type functionname(argument of type T ) { // body of function with Type T } The following example declares a function template max(x, y) which returns either x or y, whichever is larger template <class myType> myType max (myType a, myType b) { return (a>b?a:b);} The above definition of function max() can work with different kinds of data types. A function template does not occupy space in memory. The actual definition of a function template is generated when the function is called with a specific data type. The function template does not save memory. Cont… • A class template provides a specification for generating classes based on parameters. Class templates are commonly used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments. The C++ Standard Library contains many class templates, in particular the containers adapted from the Standard Template Library, such as vector. • Template specialization • It is possible to define a different implementation for a template when a specific type is passed as template argument. This is called a template specialization. For example, let's suppose that we have a very simple class called mycontainer that can store one element of any type and that has just one member function called increase, which increases its value. But we find that when it stores an element of type char it would be more convenient to have a completely different implementation with a function memberuppercase,