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

Сообщение Re: Получить сигнатуру из ламбды от 12.08.2020 14:42

Изменено 12.08.2020 14:48 YuriV

Re: Получить сигнатуру из ламбды
Здравствуйте, Barbar1an, Вы писали:

B>если у нас


B>

B>template<class L> Subscribe(L lambda)
B>{
B>    std::function<сигнатура вызова lambdы> f; // типа void(int, int)
B>    std::function<void(сигнатура параметров lambdы)> f; // типа только "int, int"
B>}

B>Subscribe([](int, int){});
B>



B>возможно както?


namespace fn {

/**
 * \Note Function details description
 */
template<typename Sign, typename R, typename... Args>
struct traits_base {
  using signature = Sign;
  using is_method = std::is_member_function_pointer<signature>;
  using args = std::tuple<Args...>;
  using arity = std::integral_constant<unsigned, sizeof...(Args)>;
  using result = R;
};

/**
 * \Note Function details specializations
 */
template<typename T>
struct traits : traits<decltype(&T::operator())> {};
template<typename R, typename... Args>
struct traits<R(*)(Args...)> : traits_base<R(*)(Args...), R, Args...> {};
template<typename R, typename... Args>
struct traits<R(* const)(Args...)> : traits_base<R(* const)(Args...), R, Args...> {};
#if __cplusplus >= 201703
template<typename R, typename... Args>
struct traits<R(*)(Args...) noexcept> : traits_base<R(*)(Args...), R, Args...> {};
template<typename R, typename... Args>
struct traits<R(* const)(Args...) noexcept> : traits_base<R(* const)(Args...), R, Args...> {};
#endif // __cplusplus >= 201703
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...)> : traits_base<R(C::*)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...)> : traits_base<R(C::* const)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) const> : traits_base<R(C::*)(Args...) const, R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) const> : traits_base<R(C::* const)(Args...) const, R, Args...> {};
#if __cplusplus >= 201703
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) noexcept> : traits_base<R(C::*)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) noexcept> : traits_base<R(C::* const)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) const noexcept> : traits_base<R(C::*)(Args...) const, R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) const noexcept> : traits_base<R(C::* const)(Args...) const, R, Args...> {};
#endif // __cplusplus >= 201703

} // namespace fn

// use, e.g. std::function<fn::traits<L>::signature> f;


Список аргументов можно добыть через tuple<Args...> to parameter pack mapping. Здесь недостаёт recognition rules для function volatile qualifier только.
Re: Получить сигнатуру из ламбды
Здравствуйте, Barbar1an, Вы писали:

B>если у нас


B>

B>template<class L> Subscribe(L lambda)
B>{
B>    std::function<сигнатура вызова lambdы> f; // типа void(int, int)
B>    std::function<void(сигнатура параметров lambdы)> f; // типа только "int, int"
B>}

B>Subscribe([](int, int){});
B>



B>возможно както?


namespace fn {

/**
 * \Note Function details description
 */
template<typename Sign, typename R, typename... Args>
struct traits_base {
  using signature = Sign;
  using is_method = std::is_member_function_pointer<signature>;
  using args = std::tuple<Args...>;
  using arity = std::integral_constant<unsigned, sizeof...(Args)>;
  using result = R;
};

/**
 * \Note Function details specializations
 */
template<typename T>
struct traits : traits<decltype(&T::operator())> {};
template<typename R, typename... Args>
struct traits<R(*)(Args...)> : traits_base<R(*)(Args...), R, Args...> {};
template<typename R, typename... Args>
struct traits<R(* const)(Args...)> : traits_base<R(* const)(Args...), R, Args...> {};
#if __cplusplus >= 201703
template<typename R, typename... Args>
struct traits<R(*)(Args...) noexcept> : traits_base<R(*)(Args...), R, Args...> {};
template<typename R, typename... Args>
struct traits<R(* const)(Args...) noexcept> : traits_base<R(* const)(Args...), R, Args...> {};
#endif // __cplusplus >= 201703
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...)> : traits_base<R(C::*)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...)> : traits_base<R(C::* const)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) const> : traits_base<R(C::*)(Args...) const, R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) const> : traits_base<R(C::* const)(Args...) const, R, Args...> {};
#if __cplusplus >= 201703
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) noexcept> : traits_base<R(C::*)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) noexcept> : traits_base<R(C::* const)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) const noexcept> : traits_base<R(C::*)(Args...) const, R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) const noexcept> : traits_base<R(C::* const)(Args...) const, R, Args...> {};
#endif // __cplusplus >= 201703

} // namespace fn

// use, e.g. std::function<typename fn::traits<L>::signature> f;


Список аргументов можно добыть через tuple<Args...> to parameter pack mapping. Здесь недостаёт recognition rules для function volatile qualifier только.