Вывод сигнатуры вызова lambda или произвольного вызываемого для «make_function»

В некоторых ситуациях желательно иметь возможность стирать вызываемые вызовы (например, функцию, указатель на функцию, экземпляр объекта с помощью operator() , lambda, mem_fn ), например, при использовании адаптеров Boost с C ++ 11 lambdas, где назначается копирование и требуется по умолчанию тип.

std::function была бы идеальной, но, похоже, нет способа автоматически определить, какая подпись создает экземпляр шаблона classа std::function with. Есть ли простой способ получить подпись функции произвольного вызываемого и / или обернуть его в соответствующий экземпляр экземпляра std::function (т. make_function Шаблон функции make_function )?

В частности, я ищу тот или иной

 template using get_signature = ...; template std::function<get_signature> make_function(F &&f) { ... } 

так что make_function([](int i) { return 0; }) возвращает std::function . Очевидно, что это не должно было бы работать, если экземпляр может быть вызван более чем одной сигнатурой (например, объекты с более чем одним, шаблон или параметр-параметр- operator() ).

Boost отлично, хотя предпочтительны не-Boost решения, которые не являются чрезмерно сложными.


Изменить: отвечая на мой вопрос.

Я придумал довольно неприятное небиблиотечное решение, используя тот факт, что lambdas имеет operator() :

 template struct remove_class { }; template struct remove_class { using type = R(A...); }; template struct remove_class { using type = R(A...); }; template struct remove_class { using type = R(A...); }; template struct remove_class { using type = R(A...); }; template struct get_signature_impl { using type = typename remove_class< decltype(&std::remove_reference::type::operator())>::type; }; template struct get_signature_impl { using type = R(A...); }; template struct get_signature_impl { using type = R(A...); }; template struct get_signature_impl { using type = R(A...); }; template using get_signature = typename get_signature_impl::type; template using make_function_type = std::function>; template make_function_type make_function(F &&f) { return make_function_type(std::forward(f)); } 

Любые идеи, где это можно упростить или улучшить? Любые очевидные ошибки?

Невозможно. Вы можете взять адрес operator() для некоторых типов, но не для произвольного вызываемого, потому что он может иметь перегрузки или параметры шаблона. Независимо от того, будет ли это работать на lambda, наверняка не определено, AFAIK.

Для невариантных не-генерических безщеточных lambda-функций, а также простых свободных функций можно использовать следующий подход:

 #include  #include  template< typename L, typename R, typename ...A > constexpr auto // std::function< R (A...) > to_function_pointer(L l, R (L::*)(A...) const) { return static_cast< R (*)(A...) >(l); } template< typename L, typename R, typename ...A > constexpr auto // std::function< R (A...) > to_function_pointer(L l, R (L::*)(A...)) // for mutable lambda { return static_cast< R (*)(A...) >(l); } template< typename L > constexpr auto to_function_pointer(L l) { return to_function_pointer(l, &L::operator ()); } template< typename R, typename ...A > constexpr auto // std::function< R (A...) > to_function_pointer(R (* fp)(A...)) { return fp; } namespace { void f() { std::cout << __PRETTY_FUNCTION__ << std::endl; } } int main() { to_function_pointer([] () { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); //to_function_pointer([&] () { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); // can't cast from non-captureless lambda to function pointer to_function_pointer([] () mutable { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); to_function_pointer(f)(); to_function_pointer(&f)(); return EXIT_SUCCESS; } Пространство #include  #include  template< typename L, typename R, typename ...A > constexpr auto // std::function< R (A...) > to_function_pointer(L l, R (L::*)(A...) const) { return static_cast< R (*)(A...) >(l); } template< typename L, typename R, typename ...A > constexpr auto // std::function< R (A...) > to_function_pointer(L l, R (L::*)(A...)) // for mutable lambda { return static_cast< R (*)(A...) >(l); } template< typename L > constexpr auto to_function_pointer(L l) { return to_function_pointer(l, &L::operator ()); } template< typename R, typename ...A > constexpr auto // std::function< R (A...) > to_function_pointer(R (* fp)(A...)) { return fp; } namespace { void f() { std::cout << __PRETTY_FUNCTION__ << std::endl; } } int main() { to_function_pointer([] () { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); //to_function_pointer([&] () { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); // can't cast from non-captureless lambda to function pointer to_function_pointer([] () mutable { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); to_function_pointer(f)(); to_function_pointer(&f)(); return EXIT_SUCCESS; } 
  • Заполните непересекающиеся пустые ячейки со значением из ячейки над первым пробелом
  • Процедуры связанных типов передачи в качестве аргументов
  • Как построить несколько функций на одной фигуре в Matplotlib?
  • Почему C ++ не поддерживает функции, возвращающие массивы?
  • Как просмотреть исходный код для функции?
  • Вычисление перекрестного произведения двух векторов в Fortran 90
  • Функция с тем же именем, но другая подпись в производном classе
  • Написание собственной функции квадратного корня
  • Есть ли способ использовать два оператора «...» в функции из R?
  • Зачем переходить по ссылке const вместо значения?
  • Возrotation функции
  • Interesting Posts

    Активация Windows 10 с помощью Windows 7 Key

    Является ли глобальная память инициализирована на C ++?

    Как установить расширенные свойства файла?

    Компиляция libjpeg

    Удалите несколько объектов с помощью rm ()

    Почему удаление файлов в корзину намного медленнее, чем при использовании Shift + Del с Total Commander?

    Случайные данные в модульных тестах?

    JavaScript: разница между .forEach () и .map ()

    Как я могу подключить Pidgin с помощью Facebook-чата (XMPP)?

    Как мне заставить jQuery ждать завершения Ajax-вызова до его возвращения?

    Что интересно для IPv6?

    Как использовать обработчик Android для обновления TextView в streamе пользовательского интерфейса?

    Что такое эффективный метод разделения и агрегирования интервалов из временных строк в кадре данных?

    Разработка для Android в Eclipse: R.java не регенерирует

    Как перенести содержимое моего портативного Firefox в установленный Firefox на моем ноутбуке?

    Давайте будем гением компьютера.