I'm working with heavily templated code, where I've got a lot of "helpers" implementing somewhat common base functionality that's missing in the STL. For example:
// is_instance_v determines whether the type argument passed is an instance of the given template
// e.g. is_instance_v<std::vector<int>, std::vector> is true
template<typename, template<typename...> typename>
constexpr bool is_instance_v = false;
template<typename... Ts, template<typename...> typename U>
constexpr bool is_instance_v<U<Ts...>, U> = true;
This is a pretty useful little template. But now I've got other templates where I want to use this in a more generic way. I'd like if I could use is_instance_v as a template argument to something while only partially specifying type arguments. That way I can pass it to a template which takes a template parameter, and let it fill in the rest. Essentially, I want a template that turns into a template, like so:
// not working code - just the kind of thing I'm envisioning
template<template<typename> typename Template>
template<typename T>
using instance_comparator_t = is_instance_v<T, Template>;
// instance_comparator_t<std::vector> can now be passed to another template that expects a template<typename> arg
The above example however doesn't work. This is because, as I understand it, using declarations are for types, and this is a template.
Possible valid solutions I've thought of:
- Manually specifying each case as a separate
constexpr bool, i.e.is_instance_of_vector<T>- This works, but it just moves the problem out another layer of abstraction without really solving it.
- A templated
constexprfunction- I think this works, but then the template has to call it.
- Any template I write that could take a constexpr function is now incompatible with all the STL templates, when they otherwise don't have to be.
Is there a better way? I'm open to solutions for any version of C++, including upcoming ones.
You can wrap
is_instance_vin a class template like as shown below: