Search code examples
c++classlambdaoperator-overloadingfunction-pointers

Operations with function pointers


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

Solution

  • 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 quesiton. 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 funciton 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);
    }
    

    Live Demo

    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). Thats 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).