how to use functors as ordinary functions argument?

L

laikon

dear, all:

below is a function with a parameter of function pointer.

void f(int a, int b, int (*fp)(int, int))
{
std::cout << fp(a, b) << std::endl;
}


and f is called with functor plus as 3rd argument.

int x = 2, y = 3;
f(x, y, std::plus<int>());

but it raises an error, and how to solve it?

Thanks a lot.
 
R

red floyd

laikon said:
dear, all:

below is a function with a parameter of function pointer.

void f(int a, int b, int (*fp)(int, int))
{
std::cout << fp(a, b) << std::endl;
}


and f is called with functor plus as 3rd argument.

int x = 2, y = 3;
f(x, y, std::plus<int>());

but it raises an error, and how to solve it?

overload f.

#include <functional>
void f(int a, int b, const std::binary_function<int, int, int>& f)
{
std::cout << f(a,b) << std::endl;
}
 
P

Paul Brettschneider

red said:
overload f.

#include <functional>
void f(int a, int b, const std::binary_function<int, int, int>& f)
{
std::cout << f(a,b) << std::endl;
}

Or, since the function body is the same, use templates?

#include <iostream>

template <typename T> void f(int a, int b, const T &fp)
{
std::cout << fp(a, b) << std::endl;
}

int mult(int a, int b)
{
return a * b;
}

int main()
{
int x = 2, y = 3;

f(x, y, std::plus<int>());
f(x, y, mult);
}
 
G

Gianni Mariani

laikon said:
dear, all:

below is a function with a parameter of function pointer.

void f(int a, int b, int (*fp)(int, int))
{
std::cout << fp(a, b) << std::endl;
}


and f is called with functor plus as 3rd argument.

int x = 2, y = 3;
f(x, y, std::plus<int>());

but it raises an error, and how to solve it?

Turn f into a template ?
 
J

Juha Nieminen

laikon said:
dear, all:

below is a function with a parameter of function pointer.

void f(int a, int b, int (*fp)(int, int))
{
std::cout << fp(a, b) << std::endl;
}


and f is called with functor plus as 3rd argument.

int x = 2, y = 3;
f(x, y, std::plus<int>());

but it raises an error, and how to solve it?

Make it a template:

template<typename Functor>
void f(int a, int b, Functor fp)
{
std::cout << fp(a, b) << std::endl;
}
 
E

Erik Wikström

dear, all:

below is a function with a parameter of function pointer.

void f(int a, int b, int (*fp)(int, int))
{
std::cout << fp(a, b) << std::endl;
}


and f is called with functor plus as 3rd argument.

int x = 2, y = 3;
f(x, y, std::plus<int>());

but it raises an error, and how to solve it?

Use a function, things that uses functors are built using templates.
 
P

Pete Becker

overload f.

#include <functional>
void f(int a, int b, const std::binary_function<int, int, int>& f)
{
std::cout << f(a,b) << std::endl;
}

That won't work. std::binary_function has three typedefs, nothing more.
 
R

red floyd

Juha said:
Make it a template:

template<typename Functor>
void f(int a, int b, Functor fp)
{
std::cout << fp(a, b) << std::endl;
}

Actually, since the OP wanted an int return:

template<typename Functor>
void f(int a, int b, Functor fp)
{
std::cout << static_cast<int>(fp(a,b)) << std::endl;
}
 
K

Kai-Uwe Bux

red said:
Actually, since the OP wanted an int return:

template<typename Functor>
void f(int a, int b, Functor fp)
{
std::cout << static_cast<int>(fp(a,b)) << std::endl;
}

Huh? std::plus<int>::eek:perator() returns an int. No cast is needed. Moreover,
if other functors are passed as the fp-argument, the cast might cover up a
conceptual bug.

I guess, one could devise some template magic to implement and check the
conceptual requirement that Functor has an operator( int, int ) that
returns an int. However, I think that would be overkill in most cases.


Best

Kai-Uwe Bux
 
L

laikon

so much thanks to all the warm heart!

but the method to define f as a template function is not my
preference.

before sent that post, I have known the way as following:

template <typename T, class BinaryFunc>
void f(T a, T b, BinaryFunc func)
{
std::cout << func(a, b) << std::endl;
}

int x = 2, y = 3;
f(x, y, std::plus<int>());

for some purpose, f is to be non-template function, and it's 3rd
argument should be functor.
so this is my focus.
but untill now there seems to be no better way than a template
function f.
 
J

Juha Nieminen

Kai-Uwe Bux said:
I guess, one could devise some template magic to implement and check the
conceptual requirement that Functor has an operator( int, int ) that
returns an int. However, I think that would be overkill in most cases.

If I'm not mistaken, this will become easy with the next C++ standard.
 
B

Brian Tyler

so much thanks to all the warm heart!

but the method to define f as a template function is not my preference.

Take a look at the std algorithm library, all the functions are templates
as this is the right way to take a function object.

Function objects should usually be taken by value (like iterators), so
that function pointers can also be passed in. If "memory" is required the
functor can be wrapped in a reference wrapper, like boost::ref

Brian
 
J

Jerry Coffin

If I'm not mistaken, this will become easy with the next C++ standard.

Quite so. This is what concepts add to C++. In this case, you'd do
something like this:

concept binary_functor<typename Functor> {
typename result_type;
typename argument_type;
result_type Functor(argument_type const &);
};

To write a template that specified this, instead of 'class' or
'typename' for the template parameter, you'd use the name of the concept
that parameter is intended to model:

template <typename II, binary_functor func>
func combine(II start1, II end1, II start2, II end2, func const &f) {
II pos1, pos2;
for (pos1=start1, pos2=start2; pos1!=end11; ++pos1, ++pos2)
f(*pos1, *pos2);
return f;
}

Note that we can combine constrained parameters (binary_functor, in this
case) with unconstrained parameters (II=InputIterator, in this case). Of
course, there's no real need to do so in this case -- the standard wil
require the library to define concepts for all the usual iterator types.

Note: I haven't written much code that uses concepts yet, so please
forgive me if I've made a few minor errors here or there (but also
please correct me...)
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top