Discussion:
Question on STL Function adaptors
(too old to reply)
m***@lycos.com
2009-03-15 08:55:43 UTC
Permalink
Hi,

I am a beginner at STL and I am having a lot of trouble understanding
function adaptors. My team lead has given me the following cheat
sheet:

(1) If f = bind1st(g,x)
then f(y) means g(x,y)

(2) If f = bind2nd(g,x)
then f(y) means g(y,x)

(3) If f = mem_fun(mf)
then f(p) means p->mf()

(4) If f = mem_fun_ref(mf)
then f(r) means r.mf()

(5) If f = not1(g)
then f(x) means !g(x)

(6) If f = not2(g)
then f(x,y) means !g(x,y)


The problem is that in most of the examples of say bind2nd that I am
seeing, there is no "y" being passed [as in f(y) means g(y,x) in the
TL's cheat sheet].

Here's an example usage:
find_if(v.begin(), v.end(), bind2nd(greater<int>(), 5))
In this case:
- "greater<int>()" is the same as "g" in the cheat sheet
- 5 is x in the cheat sheet

But where is y (from the cheat sheet) being passed?

Thanks for your help!
Masood
Alf P. Steinbach
2009-03-15 09:05:34 UTC
Permalink
Post by m***@lycos.com
Hi,
I am a beginner at STL and I am having a lot of trouble understanding
function adaptors. My team lead has given me the following cheat
(1) If f = bind1st(g,x)
then f(y) means g(x,y)
(2) If f = bind2nd(g,x)
then f(y) means g(y,x)
(3) If f = mem_fun(mf)
then f(p) means p->mf()
(4) If f = mem_fun_ref(mf)
then f(r) means r.mf()
(5) If f = not1(g)
then f(x) means !g(x)
(6) If f = not2(g)
then f(x,y) means !g(x,y)
The problem is that in most of the examples of say bind2nd that I am
seeing, there is no "y" being passed [as in f(y) means g(y,x) in the
TL's cheat sheet].
find_if(v.begin(), v.end(), bind2nd(greater<int>(), 5))
- "greater<int>()" is the same as "g" in the cheat sheet
- 5 is x in the cheat sheet
But where is y (from the cheat sheet) being passed?
find_if calls the adaptor, where in each call the argument will be an element
from the collection defined by the iterators you pass in (namely here, v.begin()
and v.end()).

By the way, note that the standard library's adaptors are horribly restricted,
they have severe problems with references.

You should instead use e.g. Boost's adaptors.


Cheers & hth.,

- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!
Gert-Jan de Vos
2009-03-15 09:14:19 UTC
Permalink
Post by m***@lycos.com
Hi,
I am a beginner at STL and I am having a lot of trouble understanding
function adaptors.  My team lead has given me the following cheat
(1) If f = bind1st(g,x)
then f(y) means g(x,y)
[more examples snipped]
Post by m***@lycos.com
find_if(v.begin(), v.end(), bind2nd(greater<int>(), 5))
 - "greater<int>()" is the same as "g" in the cheat sheet
 - 5 is x in the cheat sheet
But where is y (from the cheat sheet) being passed?
I like your cheat sheet! find_if() expects a predicate function for
its 3rd argument. The boolean predicate is evaluated for each element
in the given sequence. It returns an iterator to the first element in
your sequence for which the predicate evaluates to true, or end if no
such element exists. The predicate must be callable as f(*it), where
it is of your iterator type and its return value must be (convertible
to) bool.

Your example, according to your cheat sheet, takes the binary function
bool greater(int x, int y) and binds the second argument to 5. Your
predicate is now a unary function that compares its parameter to 5,
something like:

bool my_predicate(int x)
{
return x > 5;
}

This fits exactly the requirements of find_if, at least if v is a
container of (convertible to) int elements.

Your call to find_if() returns an iterator to the first element in the
range [v.begin(), v.end()> that is greater than 5. Clear?
Bart van Ingen Schenau
2009-03-16 13:29:51 UTC
Permalink
Post by m***@lycos.com
Hi,
I am a beginner at STL and I am having a lot of trouble understanding
function adaptors.  My team lead has given me the following cheat
(2) If f = bind2nd(g,x)
then f(y) means g(y,x)
<snip>
Post by m***@lycos.com
The problem is that in most of the examples of say bind2nd that I am
seeing, there is no "y" being passed [as in f(y) means g(y,x) in the
TL's cheat sheet].
find_if(v.begin(), v.end(), bind2nd(greater<int>(), 5))
 - "greater<int>()" is the same as "g" in the cheat sheet
 - 5 is x in the cheat sheet
But where is y (from the cheat sheet) being passed?
The y from the cheat-sheet is passed in the implementation of find_if.
Note that in the call to find_if, you are not passing the result of f
(y), but instead you are passing f itself.
This is good, because find_if expects as third argument something it
can call like f(y).
Post by m***@lycos.com
Thanks for your help!
Masood
Bart v Ingen Schenau

Loading...