Download presentation
Presentation is loading. Please wait.
Published byJessie Roy Henry Modified over 9 years ago
1
CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators –E.g., calling operator< during a sort algorithm –Those expressions define type requirements –In many cases, can plug in alternative behaviors The STL allows diverse functor types –A function pointer (from Lippman, LaJoie, Moo) bool (*PF) (const string &, const string &) // function ptr type bool *pf (const string &, const string &) // function named pf –Instance of a class/struct providing operator() –Either one can be invoked (called) But may have to deal with signature (and return type)
2
CSE 332: C++ STL functors STL Functors Extend STL Algorithms Make the algorithms even more general Can be used parameterize policy –E.g., the order produced by a sorting algorithm –E.g., the order maintained by an associative container Each functor does a single, specific operation –Often implemented as small functions or classes/structs E.g., a struct with one public member function, operator() Function objects may also have member variables –Arguments not stored may be supplied at point of call –Member variables can parameterize the operation –E.g., the value k for a functor that adds k to another value –E.g., arguments for an invocation on a remote object
3
CSE 332: C++ STL functors Function Object Use in an Algorithm struct GT_magnitude : public binary_function<double, double, bool> { bool operator() (double x, double y) { return fabs(y) < fabs(x); } }; struct LT_magnitude : public binary_function<double, double, bool> { bool operator() (double x, double y) { return fabs(x) < fabs(y); } }; int main (int, char **) { vector u,v; for (double d = 0.0; d < 10.1; d += 1.0){ u.push_back (d); v.push_back (d); } sort (u.begin(), u.end(), GT_magnitude()); sort (v.begin(), v.end(), LT_magnitude()); ostream_iterator o (cout, “ ”)); copy (u.begin(), u.end(), o); copy (v.begin(), v.end(), o); return 0; }
4
CSE 332: C++ STL functors Function Use in an Algorithm #include using namespace std; struct Employee { Employee (const char * n, int i) : name_(n), id_(i) {} string name_; int id_; }; typedef Employee * EmployeePtr; ostream& operator<< (ostream & os, const EmployeePtr & e) { os name_ id_ << " "; return os; } // function for comparing EmployeePtrs bool id_compare (const EmployeePtr & e, const EmployeePtr & f) { return e->id_ id_|| (e->id == f->id && e->name name_); } int main (int, char *[]) { vector v; v.push_back(new Employee("Claire", 23451)); v.push_back(new Employee("Bob", 12345)); v.push_back(new Employee("Alice", 54321)); cout << "v: " ; copy (v.begin(), v.end(), ostream_iterator (cout)); cout << endl; // "v: Claire 23451 Bob 12345 Alice 54321 " sort (v.begin(), v.end(), id_compare); cout << "v: " ; copy (v.begin(), v.end(), ostream_iterator (cout)); cout << endl; // "v: Bob 12345 Claire 23451 Alice 54321 " // clean up: pointers "own" the heap objects for (vector ::iterator i = v.begin(); i != v.end(); ++i) { delete *i; } return 0; } function name ok here heap object
5
CSE 332: C++ STL functors Function Object Use in a Container #include using namespace std; struct Employee { Employee (const char * n, int i) : name_(n), id_(i) {} string name_; int id_; }; ostream& operator<< (ostream & os, const Employee & e) { os << e.name_ << " " << e.id_ << “ "; return os; } // set needs this (orders by name then id) bool operator< (const Employee & e, const Employee & f) { return e.name_ < f.name_ || (e.name_ == f.name_ && e.id_ < f.id_); } // orders by id then name) struct EmployeeIdComp { bool operator() (const Employee & e, const Employee & f) { return e.id_ < f.id_ || (e.id_ == f.id_ && e.name_ < f.name_); } }; int main (int, char *[]) { vector v; v.push_back(Employee("Claire", 23451)); v.push_back(Employee("Bob", 12345)); v.push_back(Employee("Alice", 54321)); cout << "v: " ; copy (v.begin(), v.end(), ostream_iterator (cout)); // "v: Claire 23451 Bob 12345 Alice 54321 " set s; s.insert(v.begin(), v.end()); cout << "s: " ; copy (s.begin(), s.end(), ostream_iterator (cout)); // "s: Alice 54321 Bob 12345 Claire 23451 “ set t; t.insert(v.begin(), v.end()); cout << "t: " ; copy (t.begin(), t.end(), ostream_iterator (cout)); // "t: Bob 12345 Claire 23451 Alice 54321 “ return 0; } function object needed temporary object
6
CSE 332: C++ STL functors STL Functor Concepts Basic Functor Concepts –Generator –Unary Function –Binary Function Adaptable Function Objects (turn functions into function objects) –Adaptable Generator –Adaptable Unary Function –Adaptable Binary Function Predicates (return a boolean result) –Predicate –Binary Predicate –Adaptable Predicate –Adaptable Binary Predicate –Strict Weak Ordering Specialized Concepts –Random Number Generator –Hash Function
7
CSE 332: C++ STL functors STL Functor Concept Hierarchy Adaptable Function Object Basic Function Object Specialized Predicate is-refined-by Generator Unary Function Binary Function Assignable Adaptable Generator Adaptable Unary Function Adaptable Binary Function Hash Function Random Number Generator Predicate Adaptable Predicate Binary Predicate Adaptable Binary Predicate Strict Weak Ordering
8
CSE 332: C++ STL functors Assignable Concept Does not refine any other STL concept Valid Expressions –Copy Constructor X(x); X x(y); X x = y; –Assignment x = y; Models of Assignable –Almost every non-const C++ built-in type … –… and function pointers … –… but not functions (cannot construct or assign them) –Here, all Basic Function Object concepts Generator, Unary Function, Binary Function And the concepts that specialize them
9
CSE 332: C++ STL functors Generator Concept Refines Assignable Abstracts pointers to 0-ary functions (no arguments) Valid Expressions –Function call signature with no arguments f() Semantics –Returns some value of type Result –Different invocations may return different values Or, can represent a constant as a 0-ary functor –Invocation may change the function object’s internal state So, operator() need not be a const member function
10
CSE 332: C++ STL functors Generator Example Goal: fill a vector with random numbers Generic generate algorithm –Fills in a range given in its 1 st and 2 nd arguments –applies Generator Concept to its 3 rd argument Here, the functor is simply a function pointer –To the C library’s (0-ary) rand() function vector v(100); generate(v.begin(), v.end(), rand);
11
CSE 332: C++ STL functors Unary Function Concept Also a refinement of Assignable Valid Expression –Function call signature with one argument f(x) –Semantics May ignore or use single argument Similar return, const semantics to generator Example - Unary Sine Functor struct sine : public unary_function { double operator()(double x) const { return sin(x); } };
12
CSE 332: C++ STL functors Binary Function Concept Also a refinement of Assignable Valid Expression –Function call signature with two arguments f(x,y) –Semantics May use or ignore either or both of its arguments Similar const and return semantics to Unary Function Example - Exponentiation Functor struct exponentiate : public binary_function { double operator()(double x, double y) const { return pow(x,y); } };
13
CSE 332: C++ STL functors Adaptable Function Objects Allow functors to be used with Function Object Adaptors Associated types – of argument(s), and especially return value How to access these associated types ? –Define Adaptable Function Object Concepts Adaptable Generator F1::result_type Adaptable Unary Function F2::argument_type F2::result_type Adaptable Binary Function F3::first_argument_type F3::second_argument_type F3::result_type Models –Function pointers like Result(*f)(Arg) do not model these concepts –Helper adapters make Adaptable Function Objects from these functions –For example ptr_fun(f) is a model of Adaptable Unary Function
14
CSE 332: C++ STL functors Adaptable Function Object Example Each value in v2 will be 3.0 larger than the corresponding element in v1 const int N = 1000; vector v1(N); vector v2(N); // random values generate(v1.begin(), v1.end(), rand); transform(v1.begin(), v1.end(), v2.begin(), bind1st(plus (), 3.0)); Adaptable Function Object Function Object Adapter (we’ll cover these in a bit)
15
CSE 332: C++ STL functors Predicate Concepts Predicate –Refinement of Unary Function –Return type must be convertible to bool Adaptable Predicate –Refinement of Predicate, Adaptable Unary Function –Adds typedef s for argument, return types Binary Predicate –Refinement of Binary Function –Return type again must be convertible to bool Adaptable Binary Predicate –Refinement of Binary Predicate, Adaptable Binary Function –Adds typedef s for the 2 arguments, return types Strict Weak Ordering –Refinement of Binary Predicate (for comparison operations) –Similar semantics to operator< but with type constraints
16
CSE 332: C++ STL functors Random Number Generator Refinement of Unary Function –Unfortunately name is similar to Generator (0-ary) Valid Expression –Function call f(N), where N is a positive integer Semantics –Returns some value of type Result –Different invocations may return different values –Normal pseudo-random distribution If function f is called many times with the same argument N then Each value in range [0,N) will appear ~ equal number of times
17
CSE 332: C++ STL functors Hash Function Refinement of Unary Function –Return type must be size_t Valid Expression –Function call f(x) Semantics –Map from argument to a size_t result –Equivalent arguments must yield same result –Used by Hashed Associative Containers
18
CSE 332: C++ STL functors Function Object Adaptors Adaptors transform one interface to another –I.e., they implement the Adapter pattern Function Object Adaptors –Perform function composition and binding –Allows fewer ad hoc function objects –Allows you to build functions as graphs (especially chains and trees) of other functions
19
CSE 332: C++ STL functors Composition and Binding with Function Objects Function Composition –f and g are both Adaptable Unary Functions –g return type is convertible to f argument type –(f ◦ g)(x) which is f(g(x)) can be written using unary_compose or compose1(f,g) Function Binding –Adaptable Binary Function to Adaptable Unary Function –Bind first argument using binder1st Where f is an object of type binder1st f(x) F(c,x) where c is constant –Bind second argument using binder2nd Where f is an object of type binder2nd f(x) F(x,c) where c is constant
20
CSE 332: C++ STL functors vector angles; //... push in some radian values... vector sines; const double pi = 3.14159265358979323846; transform(angles.begin(), angles.end(), sines.begin(), compose1(negate (), compose1(ptr_fun(sin), bind2nd(multiplies (), pi / 180.0)))); Calculate negative of sine of angles in degrees Performed as a sequence of three operations –Conversion of degrees to radians –Calculation of sine –Negation Example of Function Composition
21
CSE 332: C++ STL functors Carry out operations in some specified order template class Chain { Fun2& operator()(const Fun1 & fun1, const Fun2 & fun2) { fun1(); return fun2(); } }; Example of Explicit Call Chains
22
CSE 332: C++ STL functors Member Function Adaptors Allows use of member functions as Function Objects Similar adaptors available for non-member functions Take an X* or X& argument and call one of the X object’s member functions through that argument If the member function is virtual, call is polymorphic Three variations –Argument type X* vs. X& –Member Function takes zero vs. one argument –Encapsulates non-const vs. const member function
23
CSE 332: C++ STL functors Member Function Adaptor Example struct B { virtual void print() = 0; }; struct D1 : public B { void print() { cout << "I'm a D1" << endl; } }; struct D2 : public B { void print() { cout << "I'm a D2" << endl; } }; int main(int, char **) { vector v; v.push_back(new D1); v.push_back(new D2); v.push_back(new D2); v.push_back(new D1); for_each(v.begin(), v.end(), mem_fun(& B::print)); return 0; }
24
CSE 332: C++ STL functors Concluding Remarks Passing parameters to Function Objects –Can do by value or by reference –Same kinds of aliasing issues, etc. as with any other object Watch performance with many small function objects –Watch out especially for creation, destruction overhead –May want to inline functors constructors, destructors –Put function objects on stack instead of heap Functors offer powerful, general mechanisms –Reduce programming complexity, increase reuse –Illustrate several new uses of generic programming –Could go farther with parameterization than just algorithms Use functors to make smarter iterators and containers
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.