CSE 332: C++ STL function objects Overview of STL Function Objects Function Object (also known as a...
-
date post
19-Dec-2015 -
Category
Documents
-
view
229 -
download
0
Transcript of CSE 332: C++ STL function objects Overview of STL Function Objects Function Object (also known as a...
CSE 332: C++ STL function objects
Overview of STL Function Objects• Function Object (also known as a Functor)
– STL Function Objects support function call syntax• E.g., a class that declares and defines operator()• E.g., by being a function pointer
– GoF Command pattern may be applied to classes and structs (user-defined types)
• Encapsulate a function call as an object• Some or all of these can be member variables
– Target object reference, function to invoke, arguments
• Generic programming allows diverse types– A function pointer (example from Lippman, LaJoie, Moo)
bool (*pf) (const string &, const & string) // function pointer
bool *pf (const string &, const & string) // function named pf
– An instance of a class providing operator()
CSE 332: C++ STL function objects
Function Objects Extend STL Algorithms
• Make the algorithms even more general• Parameterize policy
– E.g., the order produced by a sorting algorithm
• Each functor does a single, specific operation– Often implemented as small classes or structs– Often has only one public member function, operator()
• Functors 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 +k functor– E.g., arguments for an invocation on a remote object
CSE 332: C++ STL function objects
Examples of Function Object Usagestruct 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<double> 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<double>
o (cout, “ ”));
copy (u.begin(), u.end(), o);
copy (v.begin(), v.end(), o);
return 0;
}
CSE 332: C++ STL function objects
Function Object Concepts• Basic Function Object Concepts
– Generator– Unary Function– Binary Function
• Adaptable Function Objects (turn functions into functors)– 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
CSE 332: C++ STL function objects
Function Object Concept Hierarchy
Adaptable Function Object
Basic Function Object
Specialized
Predicate
is-refined-byGenerator
UnaryFunction
BinaryFunction
Assignable
AdaptableGenerator
AdaptableUnary
Function
AdaptableBinary
Function
HashFunction
RandomNumber
GeneratorPredicate
AdaptablePredicate
BinaryPredicate
AdaptableBinary
Predicate
StrictWeak
Ordering
CSE 332: C++ STL function objects
Assignable Concept
• Does not refine any other STL concept• Valid Expressions
– Copy ConstructorX(x); X x(y); X x = y;
– Assignmentx = y;
• Models of Assignable– Almost every non-const C++ built-in type– Here, all Basic Function Object concepts
• Generator, Unary Function, Binary Function• And the concepts that specialize them
CSE 332: C++ STL function objects
Generator Concept
• Refines Assignable• Abstracts 0-ary functions (take 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
CSE 332: C++ STL function objects
Generator Example
• Goal: fill a vector with random numbers• Generic generate algorithm
– Fills in a range given in its 1st and 2nd arguments– applies Generator Concept to its 3rd argument
• Here, the functor is simply a function pointer– To the C library’s (0-ary) rand() function
vector<int> v(100); generate(v.begin(), v.end(), rand);
CSE 332: C++ STL function objects
Unary Function• 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,double> {
double operator()(double x) const {
return sin(x); }
};
CSE 332: C++ STL function objects
Binary Function
• Also a refinement of Assignable• Valid Expression
– Function call signature with two argumentsf(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,double,double> {
double operator()(double x, double y) const {
return pow(x,y); }
};
CSE 332: C++ STL function objects
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– Functions like Result(*f)(Arg) are not models of these concepts– Helper adapters make Adaptable Function Objects from these functions– For example ptr_fun(f) is a model of Adaptable Unary Function
CSE 332: C++ STL function objects
Adaptable Function Object Example• Each value in v2 will be 3.0 larger than the
corresponding element in v1const int N = 1000;
vector<double> v1(N); vector<double> v2(N);
// random valuesgenerate(v1.begin(), v1.end(), rand);
transform(v1.begin(), v1.end(), v2.begin(), bind1st(plus<double>(), 3.0));
Adaptable Function Object
Function Object Adapter (we’ll cover these in a bit)
CSE 332: C++ STL function objects
Predicate Concepts• Predicate
– Refinement of Unary Function– Return type must be convertible to bool
• Adaptable Predicate– Refinement of Predicate, Adaptable Unary Function– Adds typedefs 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 typedefs for the 2 arguments, return types
• Strict Weak Ordering– Refinement of Binary Predicate (for comparison operations)– Similar semantics to operator< but with type constraints
CSE 332: C++ STL function objects
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
CSE 332: C++ STL function objects
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
CSE 332: C++ STL function objects
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
CSE 332: C++ STL function objects
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<f,g> or compose1(f,g)
• Function Binding– Adaptable Binary Function to Adaptable Unary Function– Bind first argument using binder1st<BinaryFun>
• Where f is an object of type binder1st<F>• f(x) F(c,x) where c is constant
– Bind second argument using binder2nd<BinaryFun>• Where f is an object of type binder2nd<F>• f(x) F(x,c) where c is constant
CSE 332: C++ STL function objects
vector<double> angles; // ... push in some radian values ...vector<double> sines;const double pi = 3.14159265358979323846; transform(angles.begin(), angles.end(), sines.begin(),
compose1(negate<double>(), compose1(ptr_fun(sin),
bind2nd(multiplies<double>(), 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
CSE 332: C++ STL function objects
• Carry out operations in some specified order
template <class R, class List> class Chain {
Fun2& operator()(const Fun1<R, List>& fun1, const Fun2<R, List>& fun2)
{ fun1(); return fun2();
}};
Example of Explicit Call Chains
CSE 332: C++ STL function objects
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
CSE 332: C++ STL function objects
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<B*> 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;
}
CSE 332: C++ STL function objects
Concluding Remarks
• Passing parameters to Functors– 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
• Function objects are a powerful, general mechanism– Reduces programming complexity, increases reuse– Several new uses of generic programming– Could go farther with parameterization than just algorithms
• Use functors to make smarter iterators and containers