Reputation: 1663
I am attempting to figure out how to special a template class based upon the result of a template. For example, suppose I have the following basic template class:
enum class BasicType
{
UNKNOWN,
PRIMITIVE,
OBJECT
};
template <typename T>
struct traits
{
static constexpr BasicType type = BasicType::UNKNOWN;
};
I want to be able to create a specialization of traits, for example, for any types where std::is_integral_v is true. And then another specialization where another traits is true.
I tried something like this
template <typename T>
struct traits<std::enable_if_t<std::is_integral_v<T>, T>>
{
static constexpr BasicType type = BasicType::PRIMITIVE;
};
But this doesn't work.
Upvotes: 3
Views: 271
Reputation: 9825
You're close, but the problem with using enable_if like this is that it prevents type deduction. Basically, the compiler is unable to ever match your template specialization. What you can do, though, is to move the enable_if part to a second template parameter next to your T
so it can be deduced:
template <typename T, typename = void>
struct traits
{
static constexpr BasicType type = BasicType::UNKNOWN;
};
template <typename T>
struct traits<T, std::enable_if_t<std::is_integral_v<T>>>
{
static constexpr BasicType type = BasicType::PRIMITIVE;
};
This works because T
is no longer hidden behind another template. The compiler is still unable to deduce T
from std::enable_if_t<std::is_integral_v<T>>
, but because you also specified T
direclty here: struct traits<T, ...>
, the compiler can deduce T
this way, which is enough to match your specialization.
Upvotes: 7