Adam
Adam

Reputation: 159

C++ Operator Overload for Functions

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

Answers (2)

NutCracker
NutCracker

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

NathanOliver
NathanOliver

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

Related Questions