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:
constexpr bool
, i.e. is_instance_of_vector<T>
constexpr
function
Is there a better way? I'm open to solutions for any version of C++, including upcoming ones.
You can wrap is_instance_v
in a class template like as shown below:
template<typename, template<typename> typename Template> struct Test
{
template<typename, template<typename...> typename>
static constexpr bool is_instance_v = false;
template<typename... Ts, template<typename...> typename U>
static constexpr bool is_instance_v<U<Ts...>, U> = true;
};
template<typename T, template<typename> typename Template>
using instance_comparator_t = Test<T, Template>;
template<typename T, template<typename> typename Template>
constexpr bool instance_comparator_v = instance_comparator_t<T, Template>::is_instance_v;