cse 332: c++ stl functors stl functors: functions vs. function objects stl functors support function...

24
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)

Upload: jessie-roy-henry

Post on 13-Dec-2015

250 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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)

Page 2: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 3: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

Function Object Use in an Algorithmstruct 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;

}

Page 4: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

Function Use in an Algorithm#include <iostream>

#include <vector>

#include <string>

#include <iterator>

#include <algorithm>

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 << e->name_ << " " << e->id_ << " ";

return os;

}

// function for comparing EmployeePtrsbool id_compare (const EmployeePtr & e, const EmployeePtr & f) {

return e->id_< f->id_|| (e->id == f->id && e->name < f->name_);

}

int main (int, char *[]) {

vector<EmployeePtr> 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<EmployeePtr>(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<EmployeePtr>(cout));

cout << endl;

// "v: Bob 12345 Claire 23451 Alice 54321 "

// clean up: pointers "own" the heap objects

for (vector<EmployeePtr>::iterator i =

v.begin();

i != v.end(); ++i) {

delete *i;

}

return 0;

}

function name ok here

heap object

Page 5: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

Function Object Use in a Container#include <set>

#include <string>

#include <iterator>

#include <algorithm>

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<Employee> 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<Employee>(cout));

// "v: Claire 23451 Bob 12345 Alice 54321 "

set<Employee> s;

s.insert(v.begin(), v.end());

cout << "s: " ;

copy (s.begin(), s.end(),

ostream_iterator<Employee>(cout));

// "s: Alice 54321 Bob 12345 Claire 23451 “

set<Employee, EmployeeIdComp> t;

t.insert(v.begin(), v.end());

cout << "t: " ;

copy (t.begin(), t.end(), ostream_iterator<Employee>(cout));

// "t: Bob 12345 Claire 23451 Alice 54321 “

return 0;

}

function object needed

temporary object

Page 6: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 7: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

STL Functor 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

Page 8: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

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 …– … 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

Page 9: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 10: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

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);

Page 11: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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,double> {

double operator()(double x) const {

return sin(x); }

};

Page 12: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

Binary Function Concept

• 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); }

};

Page 13: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 14: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

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)

Page 15: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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 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

Page 16: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 17: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 18: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 19: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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<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

Page 20: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

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

Page 21: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

CSE 332: C++ STL functors

• 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

Page 22: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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

Page 23: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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<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;

}

Page 24: CSE 332: C++ STL functors STL Functors: Functions vs. Function Objects STL Functors support function call syntax Algorithms invoke functions and operators

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