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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With