Reputation: 159
I'm writing a program in which I want to be able to ultimately perform some standard operations (such as a +, -, *) on double
-double
functions (by double
-double
functions I mean things that take one value of type double
and spit out something else of type double
, whether these be hard-coded or lambdas). So I'd like the following examples to be possible:
#include <functional>
double f(double x)
{
return x + 5;
}
double g(double x)
{
return 2 * x;
}
int main()
{
std::function<double(double)> h = f + g;
std::function<double(double)> h_ = (f - g) * 5;
std::function<double(double)> h__ = f * g;
return 0;
}
I've tried something like the following form, but it the compiler still doesn't seem to like me adding two things of type double(double)
together.
std::function<double(double)> operator+(std::function<double(double)> &f, std::function<double(double)> &g)
{
return [=](double x)->double{ return f(x) + g(x); };
}
Is there something obvious that I'm missing that could help this to work? As a current workaround I'm calling a function of form and calling it with the correct arguments, but I can't get it to work naturally with operators.
std::function<double(double)> add_two_functions(std::function<double(double)> &f, std::function<double(double)> &g)
{
return [=](double x)->double{ return f(x) + g(x); };
}
Upvotes: 1
Views: 73
Reputation: 12263
Your mistake is that f
and g
are function pointers and, therefore, operator+
cannot be applied to them. You need to cast those function pointers to std::function<double(double)>
objects.
Something like the following would work:
#include <iostream>
#include <functional>
double f(double x) {
return x + 5;
}
double g(double x) {
return 2 * x;
}
std::function<double(double)> operator+(std::function<double(double)> const& f,
std::function<double(double)> const& g) {
return [=](double x) -> double {
return f(x) + g(x);
};
}
int main() {
using FuncType = double(double);
std::function<FuncType> a{ reinterpret_cast<FuncType*>(f) };
std::function<FuncType> b{ reinterpret_cast<FuncType*>(g) };
auto h = a + b;
std::cout << h(2.0) << std::endl; // 11
return 0;
}
Check live example
Upvotes: 1
Reputation: 180630
In f + g
, f
and g
decay to function pointers. A function pointer is not valid to use in addition, and you cannot overload operators for function pointers.
That said, you really don't need to. You can just use a lambda like
int main()
{
auto h = [](auto var){ return f(var) + g(var); };
auto h_ = [](auto var){ return (f(var) - g(var)) * 5; };
auto h__ = [](auto var){ return f(var) * g(var); };
return 0;
}
Yes, its more verbose, but its clear what you want to have happen.
Upvotes: 0