Вывод сигнатуры вызова 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; } 
  • Возвращаемый массив в функции
  • функциональный интерфейс, который ничего не принимает и ничего не возвращает
  • Ошибка: не удалось найти функцию ... в R
  • Как построить несколько функций на одной фигуре в Matplotlib?
  • Передача строки с пробелами в качестве аргумента функции в bash
  • jquery - не является функцией ошибки
  • Функция триггера jquery, когда элемент находится в viewport
  • Процедура с аргументом фиктивного аргумента предполагаемой формы должна иметь явный интерфейс
  • Есть ли способ использовать два оператора «...» в функции из R?
  • Возrotation нескольких объектов в R-функцию
  • Разница между передачей массива и указателем на функцию в C
  • Давайте будем гением компьютера.