получить указатель на функцию связанной / выведенной лямбды со статической локальной переменной - PullRequest
1 голос
/ 23 декабря 2019

Можно ли получить указатель на функцию в стиле C для захвата лямбды с использованием статических локальных переменных?

Я пытаюсь связать первый аргумент производной функции с параметром original

template <typename F>
class entry_hook
{
public:
  entry_hook(void* original, F&& hook)
  {
    static auto bound = [&](auto&&... args)
    {
      return hook(original, std::forward<decltype(args)>(args)...);
    };

    auto* function_ptr = +[](auto&&... args) // -> decltype(bound(std::forward<decltype(args)>(args)...))
    {
      return bound(std::forward<decltype(args)>(args)...);
    };
  }
};

Использование:

const auto hook = entry_hook(nullptr, [](void* original)
{
  // ...
});

Не удается скомпилировать - невозможно преобразовать замыкание в указатель на функцию

Удаление пакета параметров из лямбда-обтекателя (путем изменения следующеголинии):

  • auto* function_ptr = +[](auto&&... args) до auto* function_ptr = +[]()
  • return bound(std::forward<decltype(args)>(args)...); до return bound();

Успешно компилируется и запускается, хотя я быПредполагается, что использование пакета параметров, который может быть выведен во время компиляции лямбды, не приведет к тому, что лямбда станет закрытием как таковым (будучи необратимым для указателя на функцию, так как для этого требуется контекст)


В идеале я пытаюсь достичь:

const auto hook = entry_hook(nullptr, [](auto original, int param1, double param2)
{
  // ...
});

Где original имеет тип void(*)(int, double), а entry_hook может предоставить указатель на функцию, переданную в лямбду


Ссылка:

Этот ответer преобразует лямбда-захват в указатель на функцию C ++ лямбда с захватами в качестве указателя на функцию

Этот ответ преобразует лямбду в указатель на функцию Получение указателя функции на лямбду?

1 Ответ

1 голос
/ 23 декабря 2019

Нет: это невозможно.

Поскольку лямбда, которую вы пытаетесь преобразовать в указатель функции

[](auto && ... args) { /* something */ }

, является универсальной (и вариационной; но суть в том, что она является общей). 1) лямбда.

Таким образом, почти как (шаблонная) шаблонная функция (точнее: как структура с шаблонным шаблоном operator()) как

template <typename ... As>
SomeRetType func (As && ... as)
 { /* do something */ }

, и вы можетене имеет указателя от func()

auto fp = &func;  // same problem

, потому что func() не объект, а набор объектов.

...