template <typename, typename = void, typename = void> \
constexpr bool has_##FuncName = false; \
\
template <typename T> \
constexpr bool has_##FuncName<T, \
typename ::std::enable_if_t<::std::is_member_function_pointer_v<decltype(&T::FuncName)>>> \
= true; \
\
template <typename T, typename Ret, typename... Args> \
constexpr bool has_##FuncName<T, Ret(Args...), \
::std::void_t<decltype(::std::declval<T>().FuncName(::std::declval<Args>()...))>> \
= ::std::is_same_v<decltype(::std::declval<T>().FuncName(::std::declval<Args>()...)), Ret>; \
static_assert(true, "")