Functor and function pointers

Discussion in 'C++' started by Amit, Mar 2, 2005.

  1. Amit

    Amit Guest

    Hello all.

    If I want to use an object both as a Functor and also, if I pass a function
    pointer, how can it be done ? For instance, I have something like this

    template< typename Iter, typename Predicate>
    class MyOperation: public std::binary_function<Iter, Iter,bool>
    {
    public:
    bool operator() (const Iter &val1, const Itr &val2) const {
    return Predicate()(val1, val2);
    }
    };

    Now, if I want to add, function pointer support to this, where I could use
    it in place of the Predicate, how would I do that ? I know I can declare a
    function pointer within the class using something like

    template< typename Iter, typename Predicate>
    class MyOperation: public std::binary_function<Iter, Iter,bool>
    {
    typedef bool (*Fnptr)(typename Iter::value_type, typename
    Iter::value_type)
    public:
    bool operator() (const Iter &val1, const Itr &val2) const {
    return Predicate()(val1, val2);
    }
    };

    But then, how do I initialize the Fnptr ? I guess a constructor would be
    the one, but then I also want to use the Predicate, say something like a
    less<int> on a set container.
    Thanks.
    Amit, Mar 2, 2005
    #1
    1. Advertising

  2. Amit wrote:
    > If I want to use an object both as a Functor and also, if I pass a function
    > pointer, how can it be done ? For instance, I have something like this
    >
    > template< typename Iter, typename Predicate>
    > class MyOperation: public std::binary_function<Iter, Iter,bool>
    > {
    > public:
    > bool operator() (const Iter &val1, const Itr &val2) const {
    > return Predicate()(val1, val2);
    > }
    > };


    I think you want to do

    template<typename Iter, typename Predicate>
    class MyOperation : public std::...
    {
    Predicate pred;
    public:
    MyOperation(Predicate p) : pred(p) {}
    bool operator() ( *** ) const {
    return pred(val1, val2);
    }
    };

    > [...]


    V
    Victor Bazarov, Mar 2, 2005
    #2
    1. Advertising

  3. Amit

    Amit Guest

    "Victor Bazarov" <> wrote in message
    news:R7oVd.49234$01.us.to.verio.net...
    > Amit wrote:
    > > If I want to use an object both as a Functor and also, if I pass a

    function
    > > pointer, how can it be done ? For instance, I have something like this
    > >
    > > template< typename Iter, typename Predicate>
    > > class MyOperation: public std::binary_function<Iter, Iter,bool>
    > > {
    > > public:
    > > bool operator() (const Iter &val1, const Itr &val2) const {
    > > return Predicate()(val1, val2);
    > > }
    > > };

    >
    > I think you want to do
    >
    > template<typename Iter, typename Predicate>
    > class MyOperation : public std::...
    > {
    > Predicate pred;
    > public:
    > MyOperation(Predicate p) : pred(p) {}


    I am still not quite sure how this would still handle a Predicate function
    object and a Pointer to a function. Because you have the Predicate arguement
    as a template parameter here.
    The function I pass might be an ordinary non static non member comparison
    function.
    Sorry, if I missed anything obvious.

    > bool operator() ( *** ) const {
    > return pred(val1, val2);
    > }
    > };
    >
    > > [...]

    >
    > V
    Amit, Mar 2, 2005
    #3
  4. "Amit" <> wrote...
    >
    > "Victor Bazarov" <> wrote in message
    > news:R7oVd.49234$01.us.to.verio.net...
    >> Amit wrote:
    >> > If I want to use an object both as a Functor and also, if I pass a

    > function
    >> > pointer, how can it be done ? For instance, I have something like this
    >> >
    >> > template< typename Iter, typename Predicate>
    >> > class MyOperation: public std::binary_function<Iter, Iter,bool>
    >> > {
    >> > public:
    >> > bool operator() (const Iter &val1, const Itr &val2) const {
    >> > return Predicate()(val1, val2);
    >> > }
    >> > };

    >>
    >> I think you want to do
    >>
    >> template<typename Iter, typename Predicate>
    >> class MyOperation : public std::...
    >> {
    >> Predicate pred;
    >> public:
    >> MyOperation(Predicate p) : pred(p) {}

    >
    > I am still not quite sure how this would still handle a Predicate
    > function
    > object and a Pointer to a function. Because you have the Predicate
    > arguement
    > as a template parameter here.


    You simply need to create a helper function template that will create your
    'MyOperation' from a function pointer or a function:

    template<class I, class P>
    MyOperation<I,P> MyOp(I const &i1, I const &i2, P p)
    {
    return MyOperation<I,P>(i1, i2, p);
    }

    How did you intend to use your 'MyOperation'? Use the 'MyOp' instead:

    .. blah blah .. MyOp(iter1, iter2, some_predicate_function) ...

    or

    .. blah blah .. MyOp(iter1, iter2, some_predicate_class()) ...

    > The function I pass might be an ordinary non static non member comparison
    > function.


    Not just "might". Has to. Non-static members have totally different
    flavour and requirements.

    > Sorry, if I missed anything obvious.


    Just study the templates. Get a good book or something. Read code, the
    Standard library headers included.

    V
    Victor Bazarov, Mar 3, 2005
    #4
  5. Amit

    Guest

    Victor, would you mind modifying the attached piece of code to make it
    work with a function pointer as well - my attempts have so far failed?

    Thanks,
    Yan

    #include <iostream>

    void function() {
    std::cout << "::function()" << std::endl;
    }

    class Functor {
    public:
    void operator() () const {
    std::cout << "Functor::eek:perator()" << std::endl;
    }
    };

    template <class Functor>
    class MyOperation {
    Functor f;
    public:
    MyOperation() : f() {}
    MyOperation(Functor f_) : f(f_) {}
    void operator() () const {
    f();
    }
    };

    template<class Function>
    MyOperation<Function> MyOp(Function function) {
    return MyOperation<Function> (function);
    }

    int main() {
    MyOperation<Functor> () (); // this works
    MyOp<Functor> (Functor()) (); // this works too
    return 0;
    }
    , Mar 3, 2005
    #5
  6. wrote:
    > Victor, would you mind modifying the attached piece of code to make it
    > work with a function pointer as well - my attempts have so far failed?
    >
    > Thanks,
    > Yan


    See inline with the code:

    >
    > #include <iostream>
    >
    > void function() {
    > std::cout << "::function()" << std::endl;
    > }
    >
    > class Functor {
    > public:
    > void operator() () const {
    > std::cout << "Functor::eek:perator()" << std::endl;
    > }
    > };
    >
    > template <class Functor>
    > class MyOperation {
    > Functor f;
    > public:
    > MyOperation() : f() {}
    > MyOperation(Functor f_) : f(f_) {}
    > void operator() () const {
    > f();
    > }
    > };
    >
    > template<class Function>
    > MyOperation<Function> MyOp(Function function) {
    > return MyOperation<Function> (function);
    > }
    >
    > int main() {
    > MyOperation<Functor> () (); // this works
    > MyOp<Functor> (Functor()) (); // this works too


    MyOp(function)();

    > return 0;
    > }
    >


    V
    Victor Bazarov, Mar 3, 2005
    #6
  7. Amit

    Guest

    Neat! thanks a lot Victor. So what happens there when you call
    MyOp(function), the type of function (which is I guess void (*) ())
    gets automatically derived based on the function passed?

    Yan
    , Mar 4, 2005
    #7
  8. wrote:
    > Neat! thanks a lot Victor. So what happens there when you call
    > MyOp(function), the type of function (which is I guess void (*) ())
    > gets automatically derived based on the function passed?


    You got it!
    Victor Bazarov, Mar 4, 2005
    #8
  9. Amit wrote:
    > Hello all.
    >
    > If I want to use an object both as a Functor and also, if I pass a function
    > pointer, how can it be done ? For instance, I have something like this
    >
    > template< typename Iter, typename Predicate>
    > class MyOperation: public std::binary_function<Iter, Iter,bool>
    > {
    > public:
    > bool operator() (const Iter &val1, const Itr &val2) const {
    > return Predicate()(val1, val2);
    > }
    > };
    >
    > Now, if I want to add, function pointer support to this, where I could use
    > it in place of the Predicate, how would I do that ? I know I can declare a
    > function pointer within the class using something like
    >
    > template< typename Iter, typename Predicate>
    > class MyOperation: public std::binary_function<Iter, Iter,bool>
    > {
    > typedef bool (*Fnptr)(typename Iter::value_type, typename
    > Iter::value_type)
    > public:
    > bool operator() (const Iter &val1, const Itr &val2) const {
    > return Predicate()(val1, val2);
    > }
    > };
    >
    > But then, how do I initialize the Fnptr ? I guess a constructor would be
    > the one, but then I also want to use the Predicate, say something like a
    > less<int> on a set container.
    > Thanks.
    >
    >


    I had the same problem just recently. The easiest solution is to use
    boost::binary_traits. Look it up on boost.org.

    Here is an adaptor I have written which takes both functions and
    functors and invokes them on dereferenced pointers. This is useful if
    you're working on collections of pointers, but want to e.g. sort them
    using a predicate which applies to the pointees.

    #include <boost/functional.hpp>

    template< typename Operation >
    class indirecter_binary
    : public std::binary_function< typename
    boost::binary_traits<Operation>::first_argument_type,
    typename boost::binary_traits<Operation>::second_argument_type,
    typename boost::binary_traits<Operation>::result_type >
    {
    typedef typename
    boost::binary_traits<Operation>::first_argument_type arg1_type;
    typedef typename
    boost::binary_traits<Operation>::second_argument_type arg2_type;
    typedef typename boost::binary_traits<Operation>::result_type
    result_type;
    typedef typename boost::binary_traits<Operation>::function_type
    function_type;
    function_type op_;
    public:
    explicit indirecter_binary( Operation op ): op_(op) {}
    result_type operator() (arg1_type *lhs, arg2_type *rhs) const {
    return op_(*lhs, *rhs);
    }
    };


    As you can see, this adaptor completely abstracts from whether op_ is a
    function or a functor. Boost does the job for you, yet again :)

    Hope that helps.

    --
    Matthias Kaeppler
    Matthias Kaeppler, Mar 4, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. James Aguilar
    Replies:
    11
    Views:
    515
    Pete Becker
    Mar 30, 2005
  2. Replies:
    3
    Views:
    474
  3. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    673
  4. Replies:
    14
    Views:
    967
    Christof Warlich
    Jul 19, 2012
  5. 邹俊洋
    Replies:
    0
    Views:
    191
    邹俊洋
    Aug 12, 2013
Loading...

Share This Page