Is it possible to pass a function as a parameter in C++? - c++

Is there any way to pass a function as a parameter in C++, like the way that functions can be passed as parameters in C? I know that it's possible to pass a function as a parameter in C using function pointers, and I want to know whether the same is possible in C++.

You can do it like in C. But you can also do it the C++ way (C++11, to be exact):
// This function takes a function as an argument, which has no
// arguments and returns void.
void foo(std::function<void()> func)
{
// Call the function.
func();
}
You can pass a normal function to foo()
void myFunc();
// ...
foo(myFunc);
but you can also pass a lambda expression. For example:
foo([](){ /* code here */ });
You can also pass a function object (an object that overloads the () operator.) In general, you can pass anything that can be called with the () operator.
If you instead use the C way, then the only thing you can pass are normal function pointers.

It's possible in C++ just as in C to pass functions as parameters but with a few differences: we can use function references instead of pointers, templates types in addition to variadic template arguments. For example:
Function references:
In C, we don't have the ability to pass objects by reference. This however is possible in C++:
void f( void (&)() ) {}
f( h );
The difference between references are pointers is subtle, but important. For instance, we can't pass NULL or 0 to a function expecting a reference; the argument must be satisfied with its type immediately. References are usually preferred in most cases over pointers.
Templates:
Templates allow us to generically pass functions with variable type attributes as parameters:
template <class T, class U>
void f( T (&)( U ) ) {}
The above signature accepts a function with any return type or parameter list (the only setback is that the function must take one argument).
In addition to this feature, we can also utilize varaidic templates to allow functions with variable-length parameter lists:
template <class T, class ...U>
void f( T (&)( U... ) ) {}
int h(int, int) { .. }
bool g(std::string) { .. }
f( h );
f( g );
The implementation of f can also use perfect forwarding if we are using U&&:
template <class T, class ...U>
void f( T (&fun)( U&&...) ) {
// ...
fun( std::forward<U>(u)... );
}
There are also lambdas which are commonly bound with std::function<T(U)>.

Yes, function pointers work exactly the same way in C++ as in C.

Yes, like this:
#include <stdio.h>
typedef void (*my_func)(int);
void do_something (my_func f)
{
f (10);
}
void square (int j)
{
printf ("squared: %d\n", j * j);
}
void cube (int j)
{
printf ("cubed: %d\n", j * j * j);
}
int main (int argc, char *argv[])
{
do_something (square);
do_something (cube);
}
The output is:
squared: 100
cubed: 1000
The typedef is to make the syntax for do_something() a bit more readable.
I would like to point out that, since you are using C++ already, it is much easier ways to achieve the same with virtual functions.

Yes, it is possible.
I found a working example program (which can be tested and edited online, and illustrates the concept well): http://ideone.com/6kSTrp#view_edit_box
//this was taken from http://www.cprogramming.com/tutorial/function-pointers.html
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int); //pointer to an int function
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}

Related

What is the difference between different ways of passing a function as an argument to another function?

I have the situation where one function calls one of several possible functions. This seems like a good place to pass a function as a parameter. In this Quoara answer by Zubkov there are three ways to do this.
int g(int x(int)) { return x(1); }
int g(int (*x)(int)) { return x(1); }
int g(int (&x)(int)) { return x(1); }
...
int f(int n) { return n*2; }
g(f); // all three g's above work the same
When should which method be used? What are there differences? I prefer the simplest approach so why shouldn't the first way always be used?
For my situation, the function is only called once and I'd like to keep it simple. I have it working with pass by pointer and I just call it with g(myFunc) where myFunc is the function that gets called last.
Expanding on L.F.'s comment, it's often better to eschew function pointers entirely, and work in terms of invocable objects (things which define operator()). All of the following allow you to do that:
#include <type_traits>
// (1) unrestricted template parameter, like <algorithm> uses
template<typename Func>
int g(Func x) { return x(1); }
// (2) restricted template parameter to produce possibly better errors
template<
typename Func,
typename=std::enable_if_t<std::is_invocable_r_v<int, Func, int>>
>
int g(Func x) { return std::invoke(x, 1); }
// (3) template-less, trading a reduction in code size for runtime overhead and heap use
int g(std::function<int(int)> x) { return x(1); }
Importantly, all of these can be used on lambda functions with captures, unlike any of your options:
int y = 2;
int ret = g([y](int v) {
return y + v;
});

C++ Function type and params including their type as arguments

In my class I have a function named CallFn() which type needs to be assigned from arguments, as well as undefined number of params including their type. I then need to call another function using the data provided in the params + the function address that's stored in the class variable. What would be the best practice to do so and how can I achieve it?
Let's take this is as a pseudo-example:
class MyClass
{
public:
DWORD dwAddress = 0x12345;
// Function type A = void in the current example
// However there could be more or less arguments
A CallFn( FUNC_TYPE A, void* B, unsigned int C, bool D )
{
// Call this function
}
};
And then call it like this:
MyClass->CallFn(void, void* B, unsigned int C, bool D);
// or
MyClass->CallFn(bool, int B, DWORD C, char* D);
As before I would just have a typedef and cast it using the address manually:
typedef void( __thiscall *CallFn )( void*, unsigned int, bool );
CallFn _CallFn;
_CallFn = ( CallFn ) ( DWORD ) 0x12345;
Few ideas come to mind using modern c++ standards, such as alias declaration with using and templates, but I'm too much of a beginner to actually write ready-to use code, even after a lot of searching, so I decided to post and see whether there might be an alternative or perhaps even better way to achieve, what I want to do and possibly even improve the idea further.
Use a function template and the auto specifier. Here's a quick example.
#include <iostream>
class Example
{
public:
template<typename A>
auto test(A x) -> decltype(x)
{
return x;
}
};
int main()
{
Example obj;
/* The function below is of type int and its argument is int */
std::cout << obj.test(5) << std::endl;
return 0;
}
I don't know if you can make it work with void, but maybe you could consider overloading in that case.

Where is thee callback happening in this code?

class Add
{
Add(){cout<<"ctor";}
void operator()(int a ,int b){return a+b;}
}
int main()
{
Add(3,4);
}
Add is the functor.And functor can help in callback mechanism right? So where is it happening here??
And functor can help in callback mechanism right?
Yes. You could write a function template that uses a functor to perform a user-defined operation as part of whatever it's doing; for example:
template <typename Fn>
void do_stuff(Fn f, int a, int b) {
int c = f(a, b);
do_something(c);
}
and then inject your operation thusly:
do_stuff(Add(), 3, 4);
One specific use is the std::sort algorithm, which can use a user-supplied functor to compare types that don't support normal comparison operators.
So where is it happening here??
It isn't; your code doesn't compile. After fixing the return value (since it returns a value not void), you could create and invoke a function with
Add()(3,4);
But that's not particularly useful.

Functors - how can I use them with typedef?

This is a functor:
class add_x {
int x;
public:
add_x(int x) : x(x) {}
int operator()(int y) { return x + y; }
};
And from main I can do this:
add_x add10(10); // create my functor
int i = add10(20); // add 20 and return it
How can I combine the functor with typedef?
For instance, I came across this:
typedef int (*myfuncType)(float f, char c1,char c2);
myfuncType pt2Function = NULL;
But what am I defining here exactly? operator ()?
Function pointer is - as its name says - just a pointer to function. You cannot use a pointer to function to point to functor, which is essentially a class with overloaded () operator.
You may be interested in std::function from C++11:
#include <functional>
(...)
std::function<int(int)> fn = add_x(10);
int i = fn(20);
Edit: Ok, I see, what you are asking for.
Maybe some code will make things clear.
int fn(float a, char b, char c) { ... }
(...)
typedef int (*myFuncType)(float f, char c1, char c2);
myFuncType ptrToFun = &fn;
(*fn)(1.0f, 'a', 'z');
This typedef creates a "pointer-to-function" type. If you declare a variable of this type, then you'll be able to assign to it a pointer to function (extracted with regular & operator) and - for example - pass to another function or just store (or call this function).
std::function is a lot more flexible, because you can store in it a pointer to function, a functor or even a lambda and call them normally.
I don't understand your first question (How can I combine the functor with typedef ?), so I can't answer that - a typedef would work as it would with any other class.
Regarding your second question: the line
typedef int (*myfuncType)(float f, char c1,char c2);
gives a name (myfunctType) to the type int (*)(float, char, char) (read: "a function which takes a float and two char values and then returns an int").
So
myfuncType pt2Function = NULL;
Defines a variable which can point to such an above-mentioned function, but sets the pointer to NULL for now.
Here, myfuncTypeis a type describing a pointer of function, with three float parameters and which return an int. A functor is just a class with operator() overload. So the typedef is used just like other class.
typedef add_x add will work.

How can it be useful to overload the "function call" operator?

I recently discovered that in C++ you can overload the "function call" operator, in a strange way in which you have to write two pair of parenthesis to do so:
class A {
int n;
public:
void operator ()() const;
};
And then use it this way:
A a;
a();
When is this useful?
This can be used to create "functors", objects that act like functions:
class Multiplier {
public:
Multiplier(int m): multiplier(m) {}
int operator()(int x) { return multiplier * x; }
private:
int multiplier;
};
Multiplier m(5);
cout << m(4) << endl;
The above prints 20. The Wikipedia article linked above gives more substantial examples.
There's little more than a syntactic gain in using operator() until you start using templates. But when using templates you can treat real functions and functors (classes acting as functions) the same way.
class scaled_sine
{
explicit scaled_sine( float _m ) : m(_m) {}
float operator()(float x) const { return sin(m*x); }
float m;
};
template<typename T>
float evaluate_at( float x, const T& fn )
{
return fn(x);
}
evaluate_at( 1.0, cos );
evaluate_at( 1.0, scaled_sine(3.0) );
A algorithm implemented using a template doesn't care whether the thing being called is a function or a functor, it cares about the syntax. Either standard ones (e.g. for_each()) or your own. And functors can have state, and do all kinds of things when they are called. Functions can only have state with a static local variable, or global variables.
If you're making a class that encapsulates a function pointer, this might make the usage more obvious.
The compiler can also inline the functor and the function call. It cannot inline a function pointer, however. This way, using the function call operator can significantly improve performance when it is used for example with the standard C++ libary algorithms.
For example for implementing generators:
// generator
struct Generator {
int c = 0;
virtual int operator()() {
return c++;
}
};
int sum(int n) {
Generator g;
int res = 0;
for( int i = 0; i < n; i++ ) {
res += g();
}
return res;
}
I see potential to yet one exotic use:
Suppose you have object of unknown type and have to declare another variable of same type, like this:
auto c=decltype(a*b)(123);
When such pattern used extensively, decltype become very annoying.
This case can occur when using some smart type system that automatically invent type of result of functions and operators based on types of arguments.
Now, if each specialization of each type of that type system equipped with
magic definition of operator() like this:
template<????> class Num<???>{
//specific implementation here
constexpr auto operator()(auto...p){return Num(p...);}
}
decltype() no more needed, you can write simply:
auto c=(a*b)(123);
Because operator() of object redirects to constructor of its own type.