Как обернуть произвольный функтор на С++11?
От: Went  
Дата: 29.08.17 13:23
Оценка:
Здравствуйте. Возникла довольно тривиальная задача, но никак не могу подобрать нужный и легковесный синтаксис для ее решения.
Допустим, у нас есть некоторый объект, у которого есть оператор () с какими-то аргументами или без них. Это может быть лямбда, bind или что-то пользовательское.
auto fnc = [](int x){return x * x;};

Например, такой. Мне нужно написать универсальную функцию, которая будет принимать на вход любой подобный функтор и выдавать на выход функтор с подобной сигнатурой вызова, но который будет делать нечто (не важно что) с переданным на вход функтором. То есть:
auto wrap_fnc = wrap(fnc);
wrap_fnc(5);

Например, эта функция будет генерить функтор-обертку, который будет класть исходный функтор в список, прибиндив к нему те аргументы, которые были переданы при вызове обертки:
// псевдокод:
std::vector<std::function<void()>> global_array;
wrap(fnc)
{
  return [fnc](args...)
  {
    global_array.push_back([fnc, args...](){fnc(args...)});
  }
}

Кручу-верчу, но никак не могу определиться даже с тем, каким шаблоном должна быть функция wrap.
Re: Как обернуть произвольный функтор на С++11?
От: night beast СССР  
Дата: 29.08.17 13:45
Оценка: 2 (1)
Здравствуйте, Went, Вы писали:

W>Здравствуйте. Возникла довольно тривиальная задача, но никак не могу подобрать нужный и легковесный синтаксис для ее решения.

W>Допустим, у нас есть некоторый объект, у которого есть оператор () с какими-то аргументами или без них. Это может быть лямбда, bind или что-то пользовательское.
W>Кручу-верчу, но никак не могу определиться даже с тем, каким шаблоном должна быть функция wrap.

не совсем понятно что нужно.
пример использования есть?

ну и глянь видео, может про это...
Re: Как обернуть произвольный функтор на С++11?
От: Evgeny.Panasyuk Россия  
Дата: 29.08.17 13:47
Оценка:
Здравствуйте, Went, Вы писали:

W>Кручу-верчу, но никак не могу определиться даже с тем, каким шаблоном должна быть функция wrap.


В простом приближении вот так:
#include <iostream>

auto wrap = [](auto f)
{
    return [=](auto ...xs)
    {
        auto result = f(xs...);
        std::clog << result << std::endl;
        return result;
    };
};

int main()
{
    auto wrapped = wrap([](auto x, auto y){ return x + y; });
    wrapped(1, 2);
}
Re[2]: Как обернуть произвольный функтор на С++11?
От: Evgeny.Panasyuk Россия  
Дата: 29.08.17 13:49
Оценка:
А, C++11 — тогда для вывода типа результата trailing decltype, а полиморфную лямбду расписать вручную.
Re: Как обернуть произвольный функтор на С++11?
От: Voivoid Россия  
Дата: 29.08.17 14:00
Оценка:
Здравствуйте, Went, Вы писали:

W>Например, такой. Мне нужно написать универсальную функцию, которая будет принимать на вход любой подобный функтор и выдавать на выход функтор с подобной сигнатурой вызова, но который будет делать нечто

Не уверен, но похоже на функциональную композицию. Попробуй на эту тему погуглить
Re[3]: Как обернуть произвольный функтор на С++11?
От: Evgeny.Panasyuk Россия  
Дата: 29.08.17 14:29
Оценка: 25 (4)
EP>А, C++11 — тогда для вывода типа результата trailing decltype, а полиморфную лямбду расписать вручную.

То есть:
#include <iostream>

template<typename F>
struct Aux
{
    F f;

    template<typename ...Xs>
    auto operator()(Xs... xs) const -> decltype(f(xs...))
    {
        auto result = f(xs...);
        std::clog << result << std::endl;
        return result;
    }
};

template<typename F>
Aux<F> wrap(F f)
{
    return {f};
};

int main()
{
    auto wrapped = wrap([](int x, int y){ return x + y; });
    wrapped(1, 2);
}
Отредактировано 29.08.2017 14:39 Evgeny.Panasyuk . Предыдущая версия .
Re[4]: Как обернуть произвольный функтор на С++11?
От: Went  
Дата: 30.08.17 05:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>А, C++11 — тогда для вывода типа результата trailing decltype, а полиморфную лямбду расписать вручную.
Спасибо, похоже, что оно!
Re[2]: Как обернуть произвольный функтор на С++11?
От: Went  
Дата: 30.08.17 05:22
Оценка:
Здравствуйте, Voivoid, Вы писали:

V>Здравствуйте, Went, Вы писали:


W>>Например, такой. Мне нужно написать универсальную функцию, которая будет принимать на вход любой подобный функтор и выдавать на выход функтор с подобной сигнатурой вызова, но который будет делать нечто

V>Не уверен, но похоже на функциональную композицию. Попробуй на эту тему погуглить
Простите, не совсем понял как теоритический материал поможет мне с тонкостями синтаксиса
Re[3]: Как обернуть произвольный функтор на С++11?
От: Voivoid Россия  
Дата: 30.08.17 08:17
Оценка:
Здравствуйте, Went, Вы писали:

W>Здравствуйте, Voivoid, Вы писали:


V>>Здравствуйте, Went, Вы писали:


W>>>Например, такой. Мне нужно написать универсальную функцию, которая будет принимать на вход любой подобный функтор и выдавать на выход функтор с подобной сигнатурой вызова, но который будет делать нечто

V>>Не уверен, но похоже на функциональную композицию. Попробуй на эту тему погуглить
W>Простите, не совсем понял как теоритический материал поможет мне с тонкостями синтаксиса

А погуглить? Вот например — https://functionalcpp.wordpress.com/2013/08/09/function-composition/
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.