#include <type_traits>
template <template <typename...> typename M, typename T>
struct meta_checker : std::enable_if<M<T>::value, int> {};
template <template <typename...> typename M, typename T>
using meta_checker_t = meta_checker<M, T>::type;
template <typename... Ts>
struct type_list {};
template <typename Tag, template <typename...> typename M, std::size_t Priority>
struct declare : declare<Tag, M, Priority - 1> {
template <typename T>
friend consteval auto foo(declare, meta_checker_t<M, T>, type_list<T>);
};
template <typename Tag, template <typename...> typename M>
struct declare<Tag, M, 0> {
template <typename T>
friend consteval auto foo(declare, meta_checker_t<M, T>, type_list<T>);
};
template <typename Tag, template <typename...> typename M, typename T, std::size_t Priority>
struct define {
template <typename T2 = T>
friend consteval auto foo(declare<Tag, M, Priority>, meta_checker_t<M, T2>, type_list<T2>) {
return type_list<T>{};
}
};
struct a {};
int main() {
define<int, std::is_class, a, 0>{};
define<int, std::is_class, int, 1>{};
type_list<a> _ = foo(declare<int, std::is_class, 1>{}, {}, {});
}
смарите чо за гавно есть.