27
Templates and Functors 1 Joe Meehean

Templates and Functors

  • Upload
    sol

  • View
    46

  • Download
    0

Embed Size (px)

DESCRIPTION

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; - PowerPoint PPT Presentation

Citation preview

CS242 Data Structures II

Templates and Functors1Joe Meehean

Pair Class ExampleSuppose we wanted a class to store a pair of intsAccess the first using first()and the second using second()Lets call it LCPair2class LCPair{ public: LCPair(int a,int b) { this->first = a; this->second = b; } int& first() { return this->first_; } int& second() { return this->second_; } private: int first_; int second_;};3Type Independent ClassesThe type of the pair items doesnt matterclass doesnt do anything with themSuppose we wanted to make LC Pair type independentHow do we do it?Do we have to write a different pair class for every data type?

4Type Independent ClassesThe type of the pair items doesnt matterclass doesnt do anything with themSuppose we wanted to make LC Pair type independentHow do we do it?Do we have to write a different pair class for every data type?

5C++ Templatestemplate class LCPair{ public: LCPair(const Obj1& 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_;};6Class TemplatesNeed to declare what the generic/template types aretemplate generic type must follow the typename keyworde.g., template can define multiple generic types using a listtemplate Then use the declared generic type like any other type

7Class TemplatesWhen initializing a templated classmust declare what types you want it to userefer to class using ClassNamee.g., LCPair intPair;Then use it like any other class

8Class TemplatesUsing a template class9int main(){ LCPair intPair; LCPair boolPair; LCPair mixedPair;

mixedPair.first() = 7; mixedPair.second() = 4.5; int i = mixedPair.first(); float f = mixedPair.second();}Class TemplatesA class template is not a classit is a pattern for what will become a classwhen you declare a class template variablee.g., LCPair intPair;the compiler makes a whole new class filereplaces all instances of template types with declared typese.g., Obj1 replaced with int does this for each different declarationLCPair & LCPair are classes10Type Independent AlgorithmsWhat if we want to find the largest element in an array?If the element overrides the > operator,the data type of the elements is irrelevantUse Function Templates to solve this problemuses similar syntax to class templates1112/** * Comparable must provide > operator */template Comparable& findMax(Comparable* a, int size){ int maxIndex = 0; for(size_t i = 1; i < size; i++){ if( a[i] > a[maxIndex] ){ maxIndex = i; } } return a[maxIndex];} Function TemplatesTemplates and CompilersCompiler replaces all template types with actual typesIf you use methods, constructors or operators on a template typee.g., a[i] > a[maxIndex]produces compile error if not defined on concrete types13Templates and CompilersWhen using template typesalways specify required methods & constructors in commentse.g., /* Comparable must provide > operator */assume the template type is a classe.g., Obj1 obj = 0; // NO, may not compilee.g., Obj1 obj; // YES14Templates and CompilersWe always declare our classes in a .h fileAnd define their methods in a .cpp fileMany compilers cannot do this with templatesincluding Visual Studio and g++Template classes must be completely defined in the .h file15Questions?1617/** * Comparable must provide > operator */template Comparable& findMax(Comparable* a, int size){ int maxIndex = 0; for(size_t i = 1; i < size; i++){ if( a[i] > a[maxIndex] ){ maxIndex = i; } } return a[maxIndex];} Recall: Function TemplatesComparing ObjectsWhat if we want findMax to work for more complex objectse.g., Student objecthas Name, GPA, GradDatewhat should > compare them on?what if we want to be able to find max Name OR max GPA all with one function?18Comparing ObjectsWhat if we want findMax to work for more complex objectse.g., Student objecthas Name, GPA, GradDatewhat should > compare them on?what if we want to be able to find max Name OR max GPA all with one function?19FunctorsFunctorsObjects that act like functionsmay have no datarequire only one public methodCan make lots of different functors for same classUsing templates we can compare any element using any functor that takes that element as a parameter2021// compare students by nameclass StudentNameCmp{ public: bool isGreaterThan( const Student& lhs, const Student& rhs){ return lhs.getName() > rhs.getName(); }};

// compare students by gpaclass StudentGPACmp{ public: bool isGreaterThan( 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){ int maxIndex = 0; for(size_t i = 1; i < size; i++){ if( cmp.isGreaterThan(a[i],a[maxIndex]) ){ maxIndex = i; } } return a[maxIndex];} 23int 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() );}FunctorsFunctorsMaking functors look like functionsInstead of defining isGreaterThan methodOverride the operator()known as the function call operatorcalling it looks just like calling a non-member function2425// compare students by nameclass StudentNameCmp{ public: bool operator()( const Student& lhs, const Student& rhs){ return lhs.getName() > rhs.getName(); }};

// compare students by gpaclass StudentGPACmp{ public: bool operator()( const Student& lhs, const Student& rhs){ return lhs.getGPA() > rhs.getGPA(); }};26/** * Comparator must provide * function operator */template Object& findMax( Object* a, int size, Comparator cmp){ int maxIndex = 0; for(size_t i = 1; i < size; i++){ if( cmp.isGreaterThan(a[i],a[maxIndex]) ){ if( cmp(a[i],a[maxIndex]) ){

maxIndex = i; } } return a[maxIndex];} Questions?27