Ошибка при выполнении программы в функции, которая возвращает другую функцию - PullRequest
1 голос
/ 22 мая 2019

Я пытаюсь вызвать функцию 'testfun' внутри функции 'test', используя 'std :: function', уменьшая число переменных на 1 и выполняя промежуточные вычисления.

Класс 'A' (вектор) содержит одномерный массив double.

Во время выполнения программа завершается в указанной точке, и «функциональный» файл открывается в «const auto _Impl = _Getimpl ();» линия. Как решить проблему?

#include <functional>

class A
{
public:
    double* d;
    unsigned s;

    A(unsigned size)
    {
        s = size;
        d = new double[s];
    }
};

double testfun(A* param, A* x)
{
    return param->d[0] + param->d[1] * x->d[0];
}

std::function<double(A*)> anon(std::function<double(A*, A*)> f, A& x, A& y)
{
    std::function<double(A*)> result = [&](A * param_)
    {
        // Program fails somewhere at that point

        double sum = 0.0;

        for (unsigned i = 0; i < x.s; i++)
            sum += f(param_, &x) - y.d[i];

        return sum;
    };

    return result;
}

double test(std::function<double(A*, A*)> f)
{
    A x(1); A y(1);
    x.d[0] = 0.0;
    y.d[0] = 2.0;

    A* param = new A(2);
    param->d[0] = 2.0; param->d[1] = 6.0;

    std::function<double(A*)> func = anon(f, x, y);

    return func(param);
}

void main()
{
    double t = test(testfun);
}

1 Ответ

2 голосов
/ 22 мая 2019

Не уверен, что это единственная проблема, но есть проблема.

В следующей функции

std::function<double(A*)> anon(std::function<double(A*, A*)> f, A& x, A& y)
{
    std::function<double(A*)> result = [&](A * param_)
    {
        // Program fails somewhere at that point

        double sum = 0.0;

        for (unsigned i = 0; i < x.s; i++)
            sum += f(param_, &x) - y.d[i];

        return sum;
    };

    return result;
}

возвращаемое лямбда получает f по ссылочному биту anon() получает f по копии.

Поэтому, когда вы вызываете возвращаемую лямбду за пределами anon(), она содержит висячую ссылку на f.

Предложение: попробуйте передать f в лямбду-копию.

// ....................................V  f by copy
std::function<double(A*)> result = [&, f](A * param_)
 { /* lambda content */ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...