Functor and function pointers

A

Amit

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.
 
V

Victor Bazarov

Amit said:
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
 
A

Amit

Victor Bazarov said:
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
 
V

Victor Bazarov

Amit said:
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
 
Y

yvinogradov

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;
}
 
V

Victor Bazarov

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
 
Y

yvinogradov

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
 
V

Victor Bazarov

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!
 
M

Matthias Kaeppler

Amit said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top