A class template is a function from type(s) to type. So it makes sense that we would be able to partially apply that function.
This is a major use case: looking at an industry-standard metaprogramming library like Boost.mp11, it’s littered with duplication of algorithms in two forms: one taking a regular (meta-)function and another with a _q suffix taking a quoted metafunction. The documentation doesn’t really explain when you would want to use a quoted metafunction, but if you do much metaprogramming, you run into it pretty quickly. It’s one way we bind arguments for partial application:
template <typename T>
struct my_func {
template <typename U>
using fn = /* some function of T and U */;
};
// we bind T so that the iteration works on a function of one argument (U)
using new_type_list = mp_transform_q<my_func<int>, old_type_list>;
And in fact Boost.mp11 also has mp_bind and friends to do this kind of partial application:
template <typename T, typename U>
using my_func = /* some function of T and U */;
using new_type_list = mp_transform_q<mp_bind<my_func, int>, old_type_list>;
But mp_bind still produces a quoted metafunction, so we still need the _q algorithms. If we had this kind of partial application more “built-in”, we could perhaps get rid of (most of? all of?) those quoted metafunctions and the algorithm duplication.
Reflection gives us a pretty straightforward way to achieve this. Partial application like this is basically a better substitute.
https://godbolt.org/z/nobr6cMrd
(It would be even better if substitute had built-in partial application that would produce a new template… we can but dream…)
If you like, you can think of this as equivalent to giving up “natural” function call syntax f(1, 2, 3) and using instead invoke(f, 1, 2, 3) so that we can treat all kinds of “functions” generically. And we could do the same sort of thing with mp_bind today, at the complexity cost of making everything a quoted metafunction. Reflection just allows us to hide that away better?
I also know the cool kids these days want to do everything with reflection and consteval programming rather than slinging types around, but there are plenty of folks who still like type-based metaprogramming and the functional style it brings. At the moment, many type-based (and especially alias-based) approaches might also be faster than leaning on consteval evaluations. Maybe we can mix a little reflection in to improve the type-based approach sometimes.
It’s entirely likely that we can go further, and metaprogramming may change much more. And yes this is only one aspect of metaprogramming, dealing with classes only, etc. But this is one step down the progress path perhaps. I wonder what an industry-standard MP library will look like in 10 years’ time.