Набросал, по ходу пьессы, компактную мета-утилитку, которая позволяет узнавать количество и типы формальных параметров, а также тип возвращаемого значения для обычных функций, функциональных объектов и лямбд. По сути, аналог boost::function_traits, только чуть более дружественный синтаксис и меньше ограничений. А главное, можно работать с лямбдами.
Ограничения:
1) Не работает для шаблонных лямбд (т.е. имеющих auto в списке формальных параметров) и классов с шаблонным operator();
2) Не работает для классов, имеющих более одного operator().
https://ideone.com/CcESHQ
Пример использования:
auto lambda = [](int, double, const std::string&) { return 42; };
using LambdaType = decltype(lambda);
static_assert(FunctionArity<LambdaType> == 3, "");
static_assert(std::is_same<int, FunctionParameterType<LambdaType, 0>>::value, "");
static_assert(std::is_same<double, FunctionParameterType<LambdaType, 1>>::value, "");
static_assert(std::is_same<const std::string&, FunctionParameterType<LambdaType, 2>>::value, "");
static_assert(std::is_same<int, FunctionReturnType<LambdaType>>::value, "");
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, rg45, Вы писали:
R>Набросал, по ходу пьессы, компактную мета-утилитку, которая позволяет узнавать количество и типы формальных параметров, а также тип возвращаемого значения для обычных функций, функциональных объектов и лямбд. По сути, аналог boost::function_traits, только чуть более дружественный синтаксис и меньше ограничений. А главное, можно работать с лямбдами.
R>Ограничения:
R>1) Не работает для шаблонных лямбд (т.е. имеющих auto в списке формальных параметров) и классов с шаблонным operator();
R>2) Не работает для классов, имеющих более одного operator().
Похоже, ограничение еще в том, что не объявлены все специализации для
const-, volatile-, and ref-qualified member functions и их комбинаций. Ну и для полноты картины повторить весь набор c ellipsis, а потом еще раз c `noexcept`
В итоге получится Boost.CallableTraits
Здравствуйте, PM, Вы писали:
PM>Похоже, ограничение еще в том, что не объявлены все специализации для const-, volatile-, and ref-qualified member functions и их комбинаций. Ну и для полноты картины повторить весь набор c ellipsis, а потом еще раз c `noexcept`
В то же время, каждая из этих специализаций, в моем варианте, пишется буквально в две строчки:
template <typename T, typename ReturnT, typename...ParamT>
struct FunctionTraits<ReturnT(T::*)(ParamT...) const> : FunctionTraits<ReturnT(ParamT...)> {};
Поэтому даже полный перебор всех комбинаций, это не такая уж страшная работа, копи-паста — нам в помощь