21
CS212: Object Oriented Analysis and Design Lecture 28: Functors

CS212: Object Oriented Analysis and Design Lecture 28: Functors

Embed Size (px)

Citation preview

Page 1: CS212: Object Oriented Analysis and Design Lecture 28: Functors

CS212: Object Oriented Analysis and Design

Lecture 28: Functors

Page 2: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Recap of Lecture 27

• STL Algorithms

• Accumulate

• Reordering algorithms

• Searching algorithm

• Removing algorithm

Page 3: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Outline of Lecture 28

• Adapters

• Predicate functions

• Function Objects

Page 4: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Iterator Adaptors

0 1 2 3 4 5 6

0 0 0 0 0 0 0

Source

Target

0 1 2 3 4 5 6

0 1 2 3 4 5 6

Source

Target

Before copy

After copy

copy(start, stop, result)

Page 5: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Iterator Adaptors

• Iterator adaptors are defined in the <iterator> header

• They are objects that act like iterators

• Don't actually point to elements of a container

• e.g. ostream_iterator

Page 6: CS212: Object Oriented Analysis and Design Lecture 28: Functors

A closer look at ostream_iterator

• They are parameterized

• We passed it two pieces of information

1. A stream to write to, in this case cout

2. A separator string

• Demonstration (Iter_Adapt.cpp)

ostream_iterator<int> myItr(cout, " ");

vector<int>::iterator it;

Page 7: CS212: Object Oriented Analysis and Design Lecture 28: Functors

ostream_iterator

• Iterator adaptors are iterators, and so they can be used in conjunction with the STL algorithms

• Supply an iterator adaptor instead to “trick” the algorithm

• Performing some complex task when it believes it's just writing values to a range

copy(myVector.begin(), myVector.end(), ostream_iterator<int>(cout, " "));

Page 8: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Common Iterator adapter

Name Example

back_insert_iteratorback_insert_iterator<vector<int> >

itr(myVector);

front_insert_iteratorfront_insert_iterator<deque<int> >

itr(myIntDeque);

insert_iteratorinsert_iterator< set<int> > itr( mySet,

mySet.begin());

ostream_iterator ostream_iterator<double> itr( myStream, "\n");

istream_iterator istream_iterator<int> itr(cin);

Page 9: CS212: Object Oriented Analysis and Design Lecture 28: Functors

A Word on Compatibility

• STL implementations are uniform

• C++ code that works on one compiler should work on any other compile

• Unfortunately, this is not the case

string ConvertToLowerCase(string text) {

transform(text.begin(), text.end(),

text.begin(), tolower); return text; }

Page 10: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Predicate functions

• Many of the STL generic algorithms take a functional argument

template <class InputIterator, class T> T accumulate (InputIterator first, InputIterator last, T init);

template< class  InputIterator, class T, class BinaryOperation >T accumulate( InputIt first, InputIt last, T init,  BinaryOperation op );

Second version uses a given binary function

The signature of the function should be equivalent to the following: Ret fun(const Type1 &a, const Type2 &b);

Demonstration (AccumCustom.cpp, SortCustom.cpp)

Page 11: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Common binary predicates

equal_to(){

if (arg1 == arg2) return TRUE;

else return FALSE;

}

not_equal_to()

greater()

less()

greater_equal()

less_equal()

logical_and()

logical_or()

Page 12: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Common arithmetic functions

• plus(){ return ( arg1 + arg2); }

• minus(){ return ( arg1 - arg2 ); }

• multiplies(){ return ( arg1 * arg2 ); }

• divides(){ return ( arg1 / arg2 ); }

• modulus(){ return ( arg1 % arg2 ); }

Page 13: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Function Objects

string mystr[] = {“Me”,”You”,”He”,”She”,”You”,”They”};

int mycount = count (mystr, myints+6, “You”);

The function uses operator == to compare the individual elements to val.

Count the number of strings that have length greater than 3

int numEvens = count_if(myVector.begin(), myVector.end(), LengthIsLessThanThree);

bool LengthIsLessThanThree(const string& str) { return str.length() < 3; }

Page 14: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Alternative design

• A function has access the following information:

• Its local variables.

• Its parameters.

• Global variables.

• This is not an optimal solution

• It is error-prone, It is not scalable, It uses global variables

bool LengthIsLessThanThree(const string& str, size_t length) { return str.length() < length;} Should be unary

Page 15: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Functors to rescue

• Issue: Unary function does not have access to enough information

• Intension: A unary function to act like a binary function without taking an extra parameter

• A functor (or function object) is an C++ class that acts like a function

• Can be accessed like objects, but behaves like functions

MyClass myFunctor;

cout << myFunctor(137) << endl;

Page 16: CS212: Object Oriented Analysis and Design Lecture 28: Functors

More on functor signature

• Create an object that overloads the function call operator, operator ()

• It is a function called operator (), not a function called operator that takes no parameters

• Defining a function that gets called if we invoke the object like a function

cout << myFunctor(137) << endl;

is equivalent to

cout << myFunctor.operator()(137) << endl;

Page 17: CS212: Object Oriented Analysis and Design Lecture 28: Functors

The operator()

• Return an object of any type (or even void)

• Can accept any number of parameters

class MyFunctor { public: void operator() (const string& str) const

{ cout << str << endl; } };

Page 18: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Functions vs Functors

• A functor's function call operator is a member function

• A raw C++ function is a free function

A function has access to

• Its local variables.

• Its parameters.

• Global variables.

A functor has access to

• Its local variables.

• Its parameters.

• Global variables.

• Class data members.

Page 19: CS212: Object Oriented Analysis and Design Lecture 28: Functors

count_if revisited

int numEvens = count_if(myVector.begin(), myVector.end(), LengthIsLessThanThree);

class ShorterThan { private:

const size_t length; public:

ShorterThan(size_t maxLength) : length(maxLength) {}bool operator() (const string& str) const {

return str.length() < length; }};

count_if(myVector.begin(), myVector.end(), ShorterThan(length));

Page 20: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Function with local state

• Those local variables can be very useful

Suppose you wanted to look at a container of XY coordinates and find the one closest to some point P.

template <class ForwardIterator> ForwardIterator min_element (ForwardIterator first, ForwardIterator last, Compare comp );

Page 21: CS212: Object Oriented Analysis and Design Lecture 28: Functors

Thank youNext Lecture: Functors