Информация об изменениях

Сообщение Re[3]: Получить сигнатуру из ламбды от 19.08.2020 13:24

Изменено 19.08.2020 13:31 Went

Разметка

Re[3]: Получить сигнатуру из ламбды
Здравствуйте. Короче, получилось что-то такое:

using namespace md;

namespace md {

void add_to_queue(const std::function<void()>& fnc)
{
  fnc(); // Для проверки просто вызываем
}

template<typename Sig>
struct defer_proxy
{
  template<typename... Args>
  void operator()(Args&&... args)
  {
    // Чтобы протащить в лямбду...
    stdext::call_traits<Sig>::parameter_types args_tuple(std::forward<Args>(args)...);  // Пакуем аргументы в туплу
    auto fn_ = std::move(fn);                                                           // И функцию в локал 

    add_to_queue([fn_, args_tuple](){stdext::call_elements(fn_, args_tuple);});} // call_elements = std::apply

  std::function<Sig> fn;
};


template<typename T>
auto defer(const T& fn) -> typename std::function<typename stdext::call_traits<T>::signature>
{
  return defer_proxy<typename stdext::call_traits<T>::signature>{fn};
}

} // md

int main(int argc, char * argv[])
{
  auto x = [](int i, float f)
  {
    std::cout << i << " " << f << std::endl;
  };
  defer(x)(1, 1.0f);

  std::function<void(int, float)> y = x;
  defer(y)(2, 2.0f);

  return 0;
}


Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?
Re[3]: Получить сигнатуру из ламбды
Здравствуйте. Короче, получилось что-то такое:

using namespace md;

namespace md {

void add_to_queue(const std::function<void()>& fnc)
{
  fnc(); // Для проверки просто вызываем
}

template<typename Sig>
struct defer_proxy
{
  template<typename... Args>
  void operator()(Args&&... args)
  {
    // Чтобы протащить в лямбду...
    stdext::call_traits<Sig>::parameter_types args_tuple(std::forward<Args>(args)...);  // Пакуем аргументы в туплу
    auto fn_ = std::move(fn);                                                           // И функцию в локал 

    add_to_queue([fn_, args_tuple](){stdext::call_elements(fn_, args_tuple);}); // call_elements = std::apply
  } 

  std::function<Sig> fn;
};


template<typename T>
auto defer(const T& fn) -> typename std::function<typename stdext::call_traits<T>::signature>
{
  return defer_proxy<typename stdext::call_traits<T>::signature>{fn};
}

} // md

int main(int argc, char * argv[])
{
  auto x = [](int i, float f)
  {
    std::cout << i << " " << f << std::endl;
  };
  defer(x)(1, 1.0f);

  std::function<void(int, float)> y = x;
  defer(y)(2, 2.0f);

  return 0;
}


Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?