170 likes | 183 Views
Learn about the concept of templates in C++, including template specifications for functions and classes, instantiation, type deduction, and template classes.
E N D
Templates How to be generic Lecture 10
In java you may have used the Object class as it is a common base type • In C++ the STL is all built using template specification, even most of the C++ library is built upon templates • template <class CharType, class Traits = char_traits<CharType>, class Allocator = allocator<CharType>> class basic _string; • typedef basic_string<char> string;
Templates • Templates let you pass the type as an argument to a function or class • Must have definition in the same file as declaration • Function templates • Generic functions • Class templates • Generic class
Function templates template <typename T> inline T const& max (T const& a, T const& b) { // if a < b then use b else use a return a<b?b:a; } typename – Represents a type we want to use The keyword class and typename are interchangeable.
Replacing template parameters with concrete types is called instantiation • Using a type that doesn’t overload the operators used in the function will result in a compile error • Arguments need to be dedicated • Max(4, 7) // ok both arguments evaluate as type integer • Max(4, 7.2f) //not ok different types
Max(static_cast<float>(4), 7.2f); //OK! • Max<float> (4, 7.2f); • You can request as many template parameters as necessary • template <typename T1, typename T2> inline T1 max (T1 const& a, T2 const& b) { return a < b ? b : a;} • First argument defines a return type!?
template <typename T1, typename T2, typename RT> inline RT max (T1 const& a, T2 const& b) { return a < b ? b : a;} • Better now we are returning a specified type. • max<int,double,double>(4,4.2) • max<double>(4,4.2) //return type is double? • The arguments however would be deduced to be int and double from the input.
Template functions can be overloaded • inline T const& max (T const& a, T const& b, T const& c) { return max (max(a,b), c); } • //3 arguments • template <typename T> inline T const& max (T const& a, T const& b) { return a<b?b:a; } • //2 arguments
Templates can take pointers to types: • template <typename T> inline T* const& max (T* const& a, T* const& b) { return *a < *b ? b : a; }
When functions are declared, they are specified to accept and return specific data types • Function templates allow functions to have generic data types • Templates can include multiple data types e.g template<typename A, typename B> • Templates consist of a definition and a call. • They are only compiled when a call is encountered • The definition of templates must be in the same file as its declaration
Template classes • template <class T> class Stack { … }; template <typename T> class Stack { Stack (Stack<T> const&); // copy constructorStack<T>& operator= (Stack<T> const&); // assignment operator};
A memeber function for stack:template<typename T> T Stack<T>::pop () { if (elems.empty()) { throw std::out_of_range("Stack<>::pop(): empty stack"); } T elem = elems.back(); // save copy of last element elems.pop_back(); // remove last element return elem; // return copy of saved element}
Template class specification • template<> class Stack<std::string> { … }; • With this any implementation must be replaced with the specified type void Stack<std::string>::push (std::string const& elem) { elems.push_back(elem); // append copy of passed elem }
It is possible to have a partial specialization • // partial specialization: second type is int template <typename T> class MyClass<T,int> { … }; MyClass<int,float> mif; // uses MyClass<T1,T2> MyClass<float,float> mff; // uses MyClass<T,T> MyClass<float,int> mfi; // uses MyClass<T,int> MyClass<int*,float*> mp; // uses MyClass<T1*,T2*>
Default template values template <typename T, typename CONT = std::vector<T> > class Stack { …} • Stack<double,std::deque<double> > • Replaces default parameter with a deque of type double.
template <typename T> class Base {…}; template <typename T> class Derived : Base<T> { …};
template <class entity_type> class IState : {//virtual void Enter(entity_type*) = 0;}; class SimulationState : public IState<Game> {//void SimulationState::Enter(Game*_game);};