When you write a trait class using partial template specialization, say
template <typename> class Foo {};
template <typename T>
struct is_instance_of_foo : std::false_type { };
template <typename T>
struct is_instance_of_foo<Foo<T>> : std::true_type { };
when the type is not exactly Foo<...> but some const / volatile / & / && qualified version of Foo the trait would evaluate to false. Is it good practice to use std::decay to strip these qualifiers?
template <typename T>
using is_instance_of_foo2 = is_instance_of_foo<std::decay_t<T>>;
Or is it expected that is_instance_of_foo<Foo<char> const &>::value is false?
I'd say this really depends on the desired semantics (equivalently: intended use) of the trait. In some contexts, you might want to cover everthing "based" on Foo<T>, in other contexts, only Foo<T> itself is what you're after.
Going by the name alone, I would probably use std::remove_cv as the wrapper. A const Foo<T> is still an instantiation of Foo. A Foo<T> & is most definitely not—it's not even a class type, it's a reference.
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