I'm struggling to figure out the syntax of function pointers and lambda functions and I need some help.
What I'm trying to do is make a class that has a parameter function pointer and be able to add, subtract, compose 2 functions. How can I achieve these?
Code:
typedef int (*mathFunc)(int);
class MathFunc {
mathFunc func = nullptr;
public:
MathFunc()=default;
MathFunc(mathFunc func) : func(func) {};
// Addition
MathFunc& operator+=(const MathFunc &f) {
// This doesn't work
this->func = [](int16_t){return this->func + *f.func};
return *this;
}
// Composition
MathFunc operator()(const MathFunc &f) {
// This doesn't work either
MathFunc result(this->func(*f.func));
return result;
}
};
MathFunc operator+(const MathFunc &f1, const MathFunc &f2) {
MathFunc result(f1);
result += f2;
return result;
}
To use a function pointer you need a function. You cannot create functions on the fly. Lambdas can decay to a function pointer when they have no captures, but you need the new function store their components. Hence a bare function pointer is the wrong tool.
Moreover, there is no clear notion of what it actually means to add two functions in your code nor in your question. I suppose you want f+g
(f and g functions) to be f(x) + g(x)
. In your code you never actually call the function. this->func + *f.func
looks like adding the value of two function pointers, which makes no sense.
You can use std::function<int(int)>
. I will only outline the approach by means of operator+=
and leave operator+
and composition for you, because it is very similar:
#include <functional>
#include <iostream>
struct my_func {
std::function<int(int)> f;
my_func& operator+=(const my_func& other) {
f = [g = other.f,h = f](int x) { return g(x) + h(x);};
return *this;
}
};
int main()
{
my_func a{ [](int x){ return x*2;}};
my_func b{ [](int x){ return x+2;}};
a += b;
std::cout << a.f(1);
}
Output is
5
because 1*2 + 1+2 is 5
In the code f = [](....
creates a function object that internally stores a copy of the old f
and a copy of other.f
as members so that they can be called later when that new function is called (a.f(1)
in main
). That's the reason you cannot use a bare function pointer. A function pointer can only point to a bare function, not to something with state (function local static variables aside).