Как преобразовать лямбда-функцию в другую, используя кортеж параметровC++

Программы на C++. Форум разработчиков
Anonymous
Как преобразовать лямбда-функцию в другую, используя кортеж параметров

Сообщение Anonymous »

Мне нужно создать оболочку для лямбда-функции, которая бы принимала кортеж параметров исходной лямбда-функции и использовала ее реализацию. Я использую компилятор C++23. Вот какую функцию я придумал:

Код: Выделить всё

template
constexpr auto wrap(Fn fn)
{
return [fn](typename lambda_traits::Args&& t) { return std::apply(fn, std::forward(t)); };
}
Чтобы это работало, мне нужно создать класс лямбда_traits, создание экземпляра которого по типу лямбда выводит тип Args, который представляет собой кортеж лямбда-параметров. Например, для лямбда-функции [](int i, int j){} Args будет иметь вид tuple.
Поэкспериментировав с возможными решениями лямбда_traits, я наконец схитрил и делегировал выведение типа std::function.

Код: Выделить всё

template struct lambda_traits;

template< class R, class ... A >
struct lambda_traits
{
using Ret = R;
using Args = std::tuple;

constexpr lambda_traits(std::function);
};

template< class R, class ... A >
lambda_traits(std::function) -> lambda_traits;

template
struct lambda_traits : decltype(lambda_traits(std::function(std::declval())))
{
};

Код: Выделить всё

std::function
здесь выглядит как клудж, я пытался заменить его, но не смог найти способ заставить его работать. Можете ли вы переработать это решение, удалив std::function?
Еще одна проблема: в некоторых случаях неявные преобразования не происходят, возможно, где-то что-то не так с типами. Можете ли вы это исправить?
Это работает:

Код: Выделить всё

static_assert(
wrap([](std::string s) { return s.size();})(std::tuple{"abc"}) == 3);
Это не так:

Код: Выделить всё

static_assert(
wrap([](const std::string& s) { return s.size();})(std::tuple{"abc"}) == 3);
Демо-версия обозревателя компилятора находится здесь.

Подробнее здесь: https://stackoverflow.com/questions/787 ... parameters

Вернуться в «C++»