Каким образом зафиксировать один аргумент в функции C++?

У меня есть 2 типа функций:

typedef double (*func_t1)(double x);
typedef double (*func_t2)(double x, double y);

Я хочу получить вот такую функцию:

func_t1 GetFunc(func_t2 f, double y)
{
    double func(double x)
    {
        return f(x, y);
    }
    return func;
}

Я понимаю что написал здесь бред. Но смысл в том, что мне нужно в функцию GetFunc подать:

  1. Функцию из двух аргументов (f)
  2. Второй аргумент для этой функции (y)

А на выходе я должен получить функцию из одного аргумента (func).

func_t1 func = GetFunc(f, 5);    
func(1); // Это f(1, 5);

Ответы (1 шт):

Автор решения: Slava

Вам необходимо использовать не указатели на функции (которые не могут принимать некоторые типы, например лямбды с захваченными данными), а std::function

using func_t1 = std::function<double( double )>;
using func_t2 = std::function<double( double, double )>;

теперь можно преобразовывать, как вам нужно:

double f2( double x, double y )
{
    std::cout << "f2(" << x << "," << y << ")" << std::endl;
    return x + y;
}

int main()
{
    using namespace std::placeholders;
    double fixed = 123;
    // используем лямбду
    func_t1 fa = [fixed]( double x ) { return f2( x, fixed ); };
    // используем std::bind
    func_t1 fb = std::bind( f2, _1, fixed );
    fa( 1 );
    fb( 2 );
}

Живой пример

Конечно, вы должны понимать, что использование std::function имеет накладные расходы

Замечание: переменная fixed в приведенном коде будет скопирована, те ее изменение после создания лямбды или вызова std::bind не изменит аргумента. Если же вам нужно менять аргумент, то в лямда нужно использовать &fixed, а в std::bind - std::ref( fixed ). При этом следует помнить, что время жизни переменной должно быть соотвественным и не короче, чем функторы, которые вы используете, иначе вы получите невалидную ссылку.

→ Ссылка