1 / 27

Templates and Functors

Templates and Functors. Joe Meehean. Pair Class Example. Suppose we wanted a class to store a pair of ints Access the first using first() and the second using second () Lets call it LCPair. class LCPair { public: LCPair ( int a ,int b) { this->first = a;

sol
Download Presentation

Templates and Functors

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. Templates and Functors Joe Meehean

  2. Pair Class Example Suppose we wanted a class to store a pair of ints Access the first using first() and the second using second() Lets call it LCPair

  3. class LCPair{ public: LCPair(inta,int b) { this->first = a; this->second = b; } int& first() { return this->first_; } int& second() { return this->second_; } private: int first_; int second_; };

  4. Type Independent Classes • The type of the pair items doesn’t matter • we don’t do anything with them • Suppose we wanted to make LC Pair type independent • How do we do it? • Do we have to write a different pair class for every data type?

  5. Type Independent Classes C++ Templates • The type of the pair items doesn’t matter • we don’t do anything with them • Suppose we wanted to make LC Pair type independent • How do we do it? • Do we have to write a different pair class for every data type?

  6. template <typename Obj1, typename Obj2> class LCPair{ public: LCPair(constObj1& o1,const Obj2& o2) { this->first_ = o1; this->second_ = o2; } Obj1& first() { return this->first_; } Obj2& second() { return this->second_; } private: Obj1 first_; Obj2 second_; };

  7. Class Templates • Need to declare what the generic/template types are • template <typenameYouChooseName> • generic type must follow the typename keyword • e.g., template <typename Obj1> • can define multiple generic types using a list • template <typenameO1,typename O2> • Then use the declared generic type like any other type

  8. Class Templates • When initializing a templated class • must declare what types you want it to use • refer to class using ClassName<type-list> • e.g., LCPair<int,int> intPair; • Then use it like any other class

  9. Class Templates int main(){ LCPair<int,int> intPair; LCPair<bool,bool> boolPair; LCPair<int,float> mixedPair; mixedPair.first() = 7; mixedPair.second() = 4.5; inti = mixedPair.first(); float f = mixedPair.second(); } Using a template class

  10. Class Templates • A class template is not a class • it is a pattern for what will become a class • when you declare a class template variable • e.g., LCPair<int,int> intPair; • the compiler makes a whole new class file • replaces all instances of template types with declared types • e.g., Obj replaced with int • does this for each different declaration • LCPair<int,int> & LCPair<bool,bool> are classes

  11. Type Independent Algorithms • What if we want to find the largest element in an array? • If the element overrides the > operator,the data type of the elements is irrelevant • Use Function Templates to solve this problem • uses similar syntax to class templates

  12. Function Templates /** * Comparable must provide > operator */ template <typename Comparable> Comparable& findMax(Comparable* a, int size){ intmaxIndex = 0; for(size_ti = 1; i < size; i++){ if( a[i] > a[maxIndex] ){ maxIndex = i; } } return a[maxIndex]; }

  13. Templates and Compilers • Compiler replaces all template types with actual types • If you use methods, constructors or operators on a template type • e.g., a[i] > a[maxIndex] • produces compile error if not defined on concrete types

  14. Templates and Compilers • When using template types • always specify required methods & constructors in comments • e.g., /* Comparable must provide > operator */ • assume the template type is a class • e.g., Obj1 obj= 0; // NO, may not compile • e.g., Obj1 obj; // YES

  15. Templates and Compilers • We always declare our classes in a .h file • And define their methods in a .cpp file • Many compilers cannot do this with templates • including Visual Studio and g++ • Template classes must be completely defined in the .h file

  16. Questions?

  17. Recall: Function Templates /** * Comparable must provide > operator */ template <typename Comparable> Comparable& findMax(Comparable* a, int size){ intmaxIndex = 0; for(size_ti = 1; i < size; i++){ if( a[i] > a[maxIndex] ){ maxIndex = i; } } return a[maxIndex]; }

  18. Comparing Objects • What if we want findMax to work for more complex objects • e.g., Student object • has Name, GPA, GradDate • what should > compare them on? • what if we want to be able to find max Name and max GPA all with one function?

  19. Comparing Objects Functors • What if we want findMax to work for more complex objects • e.g., Student object • has Name, GPA, GradDate • what should > compare them on? • what if we want to be able to find max Name and max GPA all with one function?

  20. Functors • Objects that act like functions • may have no data • require only one public method • Can make lots of different functors for same class • Using templates we can compare any element using any functor

  21. // compare students by name class StudentNameCmp{ public: boolisGreaterThan( const Student& lhs, const Student& rhs){ return lhs.getName() > rhs.getName(); } }; // compare students by gpa class StudentGPACmp{ public: boolisGreaterThan( const Student& lhs, const Student& rhs){ return lhs.getGPA() > rhs.getGPA(); } };

  22. /** * Comparator must provide * isGreaterThan(Object, Object) */ template < typename Object, typename Comparator> Object& findMax( Object* a, int size, Comparator cmp){ intmaxIndex = 0; for(size_ti = 1; i < size; i++){ if( cmp.isGreaterThan(a[i],a[maxIndex]) ){ maxIndex = i; } } return a[maxIndex]; }

  23. Functors int main(){ Student students[15]; // fill in array ... // find the largest name Student maxName = findMax(students, 15, StudentNameCmp() ); // find the student with best GPA Student bestGPA = findMax(students, 15, StudentGPACmp() ); }

  24. Functors • Making functors look like functions • Instead of defining isGreaterThan method • Override the operator() • known as the function call operator • calling it looks just like calling a non-member function

  25. // compare students by name class StudentNameCmp{ public: booloperator()( const Student& lhs, const Student& rhs){ return lhs.getName() > rhs.getName(); } }; // compare students by gpa class StudentGPACmp{ public: booloperator()( const Student& lhs, const Student& rhs){ return lhs.getGPA() > rhs.getGPA(); } };

  26. /** * Comparator must provide * function operator */ template <typename Object, typename Comparator> Object& findMax( Object* a, int size, Comparator cmp){ intmaxIndex = 0; for(size_ti = 1; i < size; i++){ if( cmp.isGreaterThan(a[i],a[maxIndex]) ){ if( cmp(a[i],a[maxIndex]) ){ maxIndex = i; } } return a[maxIndex]; }

  27. Questions?

More Related