Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specialize template class depending on trait

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.

like image 307
Patrick Wright Avatar asked Jul 16 '26 05:07

Patrick Wright


1 Answers

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.

example

like image 155
Timo Avatar answered Jul 17 '26 19:07

Timo