Reputation: 3460
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?
Upvotes: 3
Views: 129
Reputation: 171167
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.
Upvotes: 3