Can I write a trait metafunction to figure out if a type is a functor or not?
There are tons of code which can check functor using SFINAE of decltype(&T::operator())
, for instance,
template<class T>
struct is_functor {
template<class F>
static auto test(decltype(&F::operator())) -> std::true_type;
template<class F>
static auto test(...) -> std::false_type;
static constexpr bool value = decltype(test<T>(0))::value;
};
However, this doesn't work for generic lambda because generic lambda
's operator()
is a template function.
There are some code for limited case for generic lambda version which make some constraints on the argument type of generic lambda. For instance, an answer here(https://stackoverflow.com/a/5117641/2580815) won't work if lambda expression contains any expression which cannot be valid for int
type such as member access operation.
I don't need any generality for arity. In fact, I only need to know a type can be a functor which accepts only one parameter.
How can I implement my is_functor
?
Use case:
I'm trying to validate if given parameter is a functor or not for a template function, that is, I want to like some overloaded tempalte functions, for instance:
template<class F, class = enable_if_t<is_functor<std::decay_t<F>>::value>>
auto make_func(F &&f) { return std::forward<F>(f); }
template<class F, class = enable_if_t<!is_functor<std::decay_t<F>>::value>>
auto make_func(F &&f) { return [f=std::forward<F>(f)] (auto&&) { return f; }; }