views:

110

answers:

2

I have a function A that accepts a predicate function as its argument.
I have another function B and it takes a char and returns an int, and a function C that accepts int and returns a bool.

My question is how to bind B and C to pass it to function A.

Something like:

A(bindfunc(B,C))

I know boost::bind works but i am looking for STL solution.

For example,

int count(vector<int> a, pred func);    // A
//this functions counts all elements which satisfy a condition
int lastdigit(int x);                   // B
//this function outputs last digit(in decimal notation) of number x
bool isodd(int x);                      // C
//this function tells if number x is odd

// i want to find the count of all such numbers in a vector whose last digit is odd
// so i want something like
count(vector<int> a, bind(lastdigit, isodd))

One bad way would be to make a redundant function D which explicitly performs bind operation.

+1  A: 

I don't believe that the STL's bind functions are general enough for your needs.

sharth
+2  A: 

As a simple workaround for the lack of a compose higher order function in std:

template <typename F1, typename F2>
struct composer : 
    std::unary_function
    <
        typename F2::argument_type, 
        typename F1::result_type
    >
{
    composer(F1 f1_, F2 f2_) : f1(f1_), f2(f2_) {}

    typename F1::result_type 
    operator()(typename F2::argument_type x)
    { return f1(f2(x)); }

private:
    F1 f1;
    F2 f2;
};

template <typename F1, typename F2>
composer<F1, F2> compose(F1 f1, F2 f2) 
{ return composer<F1, F2>(f1, f2); }

Note that it doesn't work for binary functions (more work is involved), and that your functions must be STL function objects. It means that if you have function pointers, you must wrap them with std::ptr_fun.

Alexandre C.
this is an awesome reply, i am curious to know what do you do. I started believing that it can't be done with stl and i have to switch to boost soon. BTW i am now thinking why stl does not provide compose function. i also searched for boost::compose and got to know its deprecated and wondering why so.
mukul
@mukul: The standard library doesn't have it because frankly its design sucks when it comes to functional stuff. `Boost.Bind`'s more generic and expressive nature removes even the need for a compose functor.
GMan
you people are awesome here. looks like there won't be any question whose answer this site's user don't have. great work. hats off.and thanks to all of you for giving such beautiful replies and so quickly
mukul
@GMan: it doesn't explain why STL doesn't have `compose`, nor `transform_iterator`. I find `boost::bind` unnatural for mere function composing.
Alexandre C.
@Alexandre: Bad library design -> lack of functionality.
GMan
@Alexandre: i was trying to make a little generic composer function(return of function 2 becomes 1st argument for function 1,return of function 3 becomes 2nd argument for function 1 and so on) for stl using ellipses but every time i get some or other error. May be I am running after a wild goose. Is such a function possible? if yes then please give me a clue.
mukul
@mukul: Writing a generic compose function is a pain in the ass. You have to write one functor for each number of arguments.
Alexandre C.