创建类型特征以检测 C++ 中的函子
Creating a type trait to detect functors in C++
考虑以下自定义定义:
A functor is a (possibly final) (possibly union) class with a publicly overloaded operator()
.
如何定义类型特征:
template <class T>
struct is_functor {
static constexpr bool value = /* something */
};
template <class T>
inline constexpr bool is_functor_v = is_functor<T>::value;
当 T
是这样一个函子时,它的值为 true
,否则 false
,在标准 C++17
?
中
尝试一下(non-working欢迎反例)
struct _argument {
template <class T> constexpr operator T&() const& noexcept;
template <class T> constexpr operator T&&() const&& noexcept;
};
template <class F, class Args = std::tuple<>, std::size_t N = 128, class = void>
struct _min_arity {};
template <class F, template <class...> class T, class... Args, std::size_t N>
struct _min_arity<F, T<Args...>, N, std::enable_if_t<sizeof...(Args) <= N>>
: std::conditional_t<
std::is_invocable_v<F, Args...>,
std::integral_constant<std::size_t, sizeof...(Args)>,
_min_arity<F, std::tuple<Args..., _argument>, N>
> {};
template <class F, class = void, class = void>
struct _has_function_call_operator
: std::false_type
{};
template <class F>
struct _has_function_call_operator<
F,
std::enable_if_t<std::is_class_v<F> || std::is_union_v<F>>,
std::void_t<decltype(_min_arity<F>::value)>
>
: std::true_type
{};
template <class T>
struct is_functor
: std::bool_constant<_has_function_call_operator<T>::value>
{};
考虑以下自定义定义:
A functor is a (possibly final) (possibly union) class with a publicly overloaded
operator()
.
如何定义类型特征:
template <class T>
struct is_functor {
static constexpr bool value = /* something */
};
template <class T>
inline constexpr bool is_functor_v = is_functor<T>::value;
当 T
是这样一个函子时,它的值为 true
,否则 false
,在标准 C++17
?
尝试一下(non-working欢迎反例)
struct _argument {
template <class T> constexpr operator T&() const& noexcept;
template <class T> constexpr operator T&&() const&& noexcept;
};
template <class F, class Args = std::tuple<>, std::size_t N = 128, class = void>
struct _min_arity {};
template <class F, template <class...> class T, class... Args, std::size_t N>
struct _min_arity<F, T<Args...>, N, std::enable_if_t<sizeof...(Args) <= N>>
: std::conditional_t<
std::is_invocable_v<F, Args...>,
std::integral_constant<std::size_t, sizeof...(Args)>,
_min_arity<F, std::tuple<Args..., _argument>, N>
> {};
template <class F, class = void, class = void>
struct _has_function_call_operator
: std::false_type
{};
template <class F>
struct _has_function_call_operator<
F,
std::enable_if_t<std::is_class_v<F> || std::is_union_v<F>>,
std::void_t<decltype(_min_arity<F>::value)>
>
: std::true_type
{};
template <class T>
struct is_functor
: std::bool_constant<_has_function_call_operator<T>::value>
{};