Перегрузка оператора C ++ для функций - PullRequest
1 голос
/ 22 января 2020

Я пишу программу, в которой я хочу иметь возможность в конечном итоге выполнять некоторые стандартные операции (такие как +, -, *) над double - double функциями (double - double функции Я имею в виду вещи, которые принимают одно значение типа double и выделяют что-то другое типа double, будь то жестко запрограммированные или лямбда-выражения). Поэтому я хотел бы, чтобы были возможны следующие примеры:

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

Я пробовал что-то вроде следующей формы, но компилятору все еще не нравится, когда я добавляю две вещи типа double(double) вместе.

std::function<double(double)> operator+(std::function<double(double)> &f, std::function<double(double)> &g)
{
    return [=](double x)->double{ return f(x) + g(x); };
}

Есть ли что-то очевидное, чего мне не хватает, что могло бы помочь этому сработать? В качестве текущего обходного пути я вызываю функцию формы и вызываю ее с правильными аргументами, но не могу заставить ее работать естественным образом с операторами.

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

Ответы [ 2 ]

1 голос
/ 22 января 2020

Ваша ошибка в том, что f и g являются функциональными указателями и, следовательно, operator+ не может быть применен к ним. Вам нужно привести эти указатели функций к std::function<double(double)> объектам.

Будет работать что-то вроде следующего:

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

Проверка живой пример

0 голосов
/ 22 января 2020

In f + g, f и g распадаются на указатели функций. Указатель функции недопустим для использования в дополнение, и вы не можете перегружать операторы для указателей функций.

Тем не менее, вам действительно не нужно. Вы можете просто использовать лямбду типа

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

Да, это более многословно, но ясно, что вы хотите, чтобы произошло.

...