Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inspect the interface of a template template class

I was trying to overload a template class with SFINAE based on whether a template template parameter had the type type defined in it (for example std::remove_reference has a type member type alias), but I cannot figure out a good way to go about doing that.

For example, I wanted to do

template <template <typename...> class Trait>
using EnableIfHasTypeMember = std::void_t<Trait::type>;

template <template <typename...> class Trait, typename OtherStuff,
          EnableIfHasTypeMember<Trait>* = nullptr>
class Something { ... }

But this gives me a compiler error. Is there any way I can go about inspecting the interface of a template template parameter?

like image 260
Curious Avatar asked Dec 24 '22 19:12

Curious


1 Answers

If I understand correctly what you're wanting, it's not possible with the level of generality that you showed in your example. You can't know whether the template has a type member type alias unless you know the arguments it's instantiated with, because it could differ based on the specialization. Example:

template <typename T>
struct my_trait
{
    using type = int;
};

template <>
struct my_trait<double> {};

How would you expect EnableIfHasTypeMember to behave in this case? That's why you can't reason about the contents of a template until it is instantiated.

It helps in situations like this to keep in mind that all instantiations of my_trait<T> for different types T are distinct types from one another. There is no actual relationship between the types; they originated from a common template, which admits the ability to write a generic implementation that is reused, but the concrete types once instantiated are wholly separate.

like image 99
Jason R Avatar answered Mar 05 '23 10:03

Jason R