
I think the emphasis is a little too focused on compilation times and not enough on the interface. That being said, a comment about the type-only predicate: Thanks to constexpr, function overloading, user-defined literals, explicit operator bool, and variable templates, that example could actually look like this: static_assert(any(odd{}, list(1_udl, 2_udl)), "1 or 2 should be odd."); And also allow the following natural looking expressions: static_assert(count(odd{}, list(1_udl, 2_udl, 3_udl)) == 2_udl, "Incorrect count of odd numbers."); static_assert(type<int> == type<decltype(0)>, "Integer literal not an int."); static_assert(common_type(type<int>, type<unsigned>, type<char>, type<signed char>) == type<unsigned>, "Incorrect common_type."); User-defined literal name of udl (user defined literal) chosen as a placeholder to avoid that being the focus. It could be anything from _mpl to _type to _t. Long compile times in a C++11 metaprogramming world are primarily defined by the number of arguments passed to constexpr functions (calling two constexpr functions with 3000 arguments instead of one constexpr function with 3000 arguments is a huge time and memory sink) and template instantiation / constexpr recursion depth. Neither of those are especially dictated by choice in interface, and I would hate to see a better interface abandoned due to premature optimization.