Template template class predicate not working in partial specialization

  • A+
Category:Languages

I have many EnableIf traits that basically check whether the input type satisfies an interface. I was trying to create a generic Resolve trait that can be used to transform those into a boolean trait.

Something like this - https://wandbox.org/permlink/ydEMyErOoaOa60Jx

template <   template <typename...> class Predicate,   typename T,   typename = std::void_t<>> struct Resolve : std::false_type {}; template <template <typename...> class Predicate, typename T> struct Resolve<Predicate, T, Predicate<T>> : std::true_type {}; 

Now if you have an EnableIf trait like so

template <typename T> using EnableIfHasFoo = std::void_t<decltype(std::declval<T>().foo())>; 

You can create a boolean version of that very quickly

template <typename T> struct HasFoo : Resolve<EnableIfHasFoo, T> {}; 

Or the analogous variable template.

But for some reason the partial specialization is not working as expected. Resolve does not work as intended. See the output here - https://wandbox.org/permlink/ydEMyErOoaOa60Jx. The same thing implemented "manually" works - https://wandbox.org/permlink/fmcFT3kLSqyiBprm

I am resorting to manually defining the types myself. Is there a detail with partial specializations and template template arguments that I am missing?

 


I cannot find the exact reason why your example don't work. If you want to dig more into the details of std::void_t, here's an interesting explanation

Even if I cannot explain it in depth, I would like to add another reliable syntax that is used in the detection idiom.

template<     template <typename...> class Predicate,     typename T,     typename = void> struct Resolve : std::false_type {};  template <template <typename...> class Predicate, typename T> struct Resolve<Predicate, T, std::void_t<Predicate<T>>> : std::true_type {};  template <typename T> using EnableIfHasFoo = decltype(std::declval<T>().foo()); 

live on compiler explorer

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: