|< C++ STL Algorithm 15 | Main | C Linux Socket Programming Tutorial 1 >| Site Index | Download |


 

 

 

 

MODULE 38

THE C++ STL FUNCTION OBJECT & MISC

 

 

 

 

My Training Period: xx hours

 

This is a final part of the C++ Standard Template Library (STL) programming tutorial series. C++ codes samples of the member functions compiled using Microsoft Visual C++ .Net, win32 empty console mode application. Source code is available in C++ function object source code samples. You can proceed to Linux Socket programming using GNU C or you can go back to the Tenouk.com main page for more C & C++ programming tutorials. Have a nice coding!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The C++ STL  function object skills that supposed to be acquired:

 

  • Able to understand and use the STL function objects.

 

What do we have in this page?

  1. Function Objects

  2. a function object program example

  3. Function objects are smart functions

  4. Each function object has its own type

  5. Function objects are usually faster than ordinary functions

  6. a function object program example

  7. Predefined Function Objects

  8. Miscellaneous

  9. Class pair

  10. make_pair() template function

  11. The auto_ptr type

  12. Numeric types

  13. Others

 

38.1  Function Objects

  • Functional arguments for algorithms don't have to be functions. They can be objects that behave as functions. Such an object is called a function object, or functor.

  • Sometimes you can use a function object when an ordinary function won't work. The STL often uses function objects and provides several function objects that are very helpful.

  • Function objects are another example of the generic programming capabilities and the concept of pure abstraction. You could say that anything that behaves like a function is a function. So, if you define an object that behaves as a function, it can be used as a function.

  • A functional behavior is something that you can call by using parentheses and passing arguments. For example:

function(arg1, arg2); // a function call

  • So, if you want objects to behave this way you have to make it possible to call them by using parentheses and passing arguments.  All you have to do is define operator() with the appropriate parameter , for example:

class XYZ

{

    public:

        // define "function call" operator

        return-value operator() (arguments) const;

...

};

  • Now you can use objects of this class to behave as a function that you can call:

XYZ foo;

...

// call operator() for function object foo

foo(arg1, arg2);

  • The call is equivalent to:

// call operator() for function object foo

foo.operator() (arg1, arg2);

  • The following is a complete example.

// function object example

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

 

// a simple function object that prints the passed argument

class PrintSomething

{

    public:

        void operator() (int elem) const

        {    cout<<elem<<' ';    }

};

 

int main()

{

    vector<int> vec;

    // insert elements from 1 to 10

    for(int i=1; i<=10; ++i)

        vec.push_back(i);

    // print all elements

    for_each (vec.begin(), vec.end(), //range

    PrintSomething()); //operation

    cout<<endl;

}

 

Output:

 

C++ STL Function object program example

PrintSomething()

for_each(vec.begin(), vec.end(),

PrintSomething());

namespace std

{

    template <class Iterator, class Operation>Operation for_each(Iterator act, Iterator end, Operation op)

    {

        while(act != end)

        {   // as long as not reached the end

            op(*act);    // call op() for actual element

            act++;        // move iterator to the next element

        }

    return op;

    }

}

PrintSomething::operator()(*act)

38.2  Function objects are smart functions

38.3  Each function object has its own type

38.4  Function objects are usually faster than ordinary functions

void add10 (int& elem)

{    elem += 10;    }

 

void funct()

{

vector<int> vec;

...

for_each(vec.begin(), vec.end(),     // range

add10);    // operation

}

template <int theValue>

void add(int& elem)

{    elem += theValue;    }

 

void funct()

{

vector<int> vec;

...

for_each (vec.begin(), vec.end(), // range

add<10>); // operation

}

  • If you process the value to add at runtime, things get complicated. You must pass the value to the function before the function is called. This normally results in some global variable that is used both by the function that calls the algorithm and by the function that is called by the algorithm to add that value. Look like a messy style.

  • If you need such a function twice, with two different values to add, and both values are processed at runtime, you can't achieve this with one ordinary function. You must either pass a tag or you must write two different functions.

  • With function objects, you can write a smarter function that behaves in the desired way because the object may have a state; it can be initialized by the correct value.

  • Here is a full example:

 

// a function object example

#include <iostream>

#include <list>

#include <algorithm>

using namespace std;

 

// a function object that adds the value with which it is initialized

class AddValue

{

    private:

        // the value to add

        int theValue;

    public:

        // constructor initializes the value to add

        AddValue(int val) : theValue(val) {    }

        // the function call for the element adds the value

        void operator() (int& elem) const

        {    elem += theValue;    }

};

 

int main()

{

list<int> lst1;

// the first call of for_each() adds 10 to each value:

for_each(lst1.begin(), lst1.end(), // range

AddValue(10)); // operation

}

AddValue (*lst1.begin())

after adding first element: 22 23 24 25 26 27 28 29 30

AddValue addx (x); // function object that adds value x

AddValue addy (y); // function object that adds value y

for_each (vec.begin(), vec.end(), // add value x to each element

addx);

...

for_each (vec.begin(), vec.end(), // add value y to each element

addy);

...

for_each (vec.begin(), vec.end(), // add value x to each element

addx);

 

38.5  Predefined Function Objects

set<int> st;

set<int, less<int> > st; // sort elements with <

set<int, greater<int> > st; // sort elements with >

transform(vec.begin(), vec.end(), // source

vec.begin(), // destination

negate<int>()); // operation

negate<int>()

// process the square of all elements

transform(vec.begin(), vec.end(), // first source

vec.begin(), // second source

vec.begin(), // destination

multiplies<int>()); // operation

 

-------------------------------------------The real End for STL topics--------------------------------------

 

38.6 Miscellaneous

 

The following items may not be covered in details in this part of tutorial but you may have encountered them somewhere in the various program examples.

 

Class pair

 

Is provided to treat two values as a single unit. It is used in several places within the C++ standard library. In particular, the container classes’ map and multimap use pairs to manage their elements, which are key/value pairs.

 

make_pair() template function

 

Enables you to create a value pair without writing the types explicitly.

 

The auto_ptr type

 

The auto_ptr type is provided by the C++ standard library as a kind of a smart pointer that helps to avoid resource leaks when exceptions are thrown.

 

Numeric types

 

In general it is platform-dependent limits. The C++ standard library provides these limits in the template numeric_limits. These numeric limits replace and supplement the ordinary preprocessor constants of C.

These constants are still available for integer types in <climits> and <limits.h>, and for floating-point types in <cfloat> and <float.h>.

The new concept of numeric limits has two advantages: First, it offers more type safety. Second, it enables a programmer to write templates that evaluate these limits. Take note that it is always better to write platform-independent code by using the minimum guaranteed precision of the types.

 

Others

 

The algorithm library, file <algorithm> header, includes three auxiliary functions, one each for the selection of the minimum and maximum of two values and one for the swapping of two values.  These auxiliary functions have been used in various program examples in this tutorial. Four template functions define the comparison operators!=, >, <=, and >= by calling the operators == and <. These functions are defined in <utility>. Don’t forget other standard C++ header files such as  <ios>, <locale>, <valarray>, <new>, <memory>, <complex> etc.

 

 

 

 

 

 

 

 

 

 

 

 

 

tenouk C++ STL tutorial

 

Further C++ related reading:

 

  1. Source code is available in C++ function object source code samples.

  2. A complete C & C++ Standard Library documentation that includes STL.

  3. Check the best selling C / C++ and STL books at Amazon.com.

  4. C++ Templates programming tutorials.

 

 

 

 

 

 

 

|< C++ STL Algorithm 15 | Main | C Linux Socket Programming Tutorial 1 >| Site Index | Download |