Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function Composition Operator

As a small exercise in functional programming in C++, I want to overload the operator* to allow me to compose 2 functions.

What stumps me is that if I define my operator like this:

std::function<float(float)> operator*(std::function<float(float)> func1, std::function<float(float)> func2)
{
   // ...
}

I cannot use it with regular functions as in:

float f(float);
float g(float);
auto composite = f*g;

Because I get:
error: invalid operands of types ‘float(float)’ and ‘float(float)’ to binary ‘operator*’

If I try to add a function pointer only version as in:

std::function<float(float)> operator*(float(*func1)(float) , float(*func2)(float))
{
   return [func1, func2](float x) { return func1(func2(x)); };
}

I get this error:
error: ‘std::function<float(float)> operator*(float (*)(float), float (*)(float))’ must have an argument of class or enumerated type

I was able to get it to work by adding a make_function helper, but that really makes the code ugly.

Is there a way to get this operator to automatically cast functions to std::function instances?

like image 710
Adi Shavit Avatar asked Oct 01 '22 16:10

Adi Shavit


1 Answers

Unfortunately, C++ does not allow operators to be overloaded for built-in types. Just as you cannot implement your own operator* for two ints, you cannot implement it for two function pointers, except if you represent these functions with the std::function type which is a class and therefore not a built-in type.

You can, however, instead of using an operator, simply use a function:

std::function<float(float)> dot(float(*func1)(float) , float(*func2)(float))
{
   return [func1, func2](float x) { return func1(func2(x)); };
}
like image 112
bitmask Avatar answered Oct 03 '22 05:10

bitmask