Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need an Enable type parameter when using std::enable_if

According to the examples in std::enable_if documentation, this compiles:

template <typename T, typename Enable = void>
struct transform {
    T operator()(nlohmann::json &data);
};

template <typename T>
struct transform<T, std::enable_if_t<std::is_integral_v<T>>> {
    T operator()(nlohmann::json &data) {
        ...
    }
};

What I don't understand is why I need the Enable type parameter when enable_if_t can evaluate to a type. In other words, why won't this compile:

template <typename T>
struct transform {
    T operator()(nlohmann::json &data);
};

template <typename T>
struct transform<std::enable_if_t<std::is_integral_v<T>, T>> {
    T operator()(nlohmann::json &data) {
        ...
    }
};
like image 550
Jason Avatar asked Oct 23 '25 15:10

Jason


1 Answers

This form of class template is considered partial specialization:

template <typename T>
struct transform<std::enable_if_t<std::is_integral_v<T>, T>> {
    T operator()(nlohmann::json &data) {
        ...
    }
};

The problem here is that std::enable_if_t<std::is_integral_v<T>, T> puts T in the so-called non-deduced context, so it's essentially impossible for the compiler to conclude which T this specialisation correspond to.

like image 81
The Dreams Wind Avatar answered Oct 25 '25 05:10

The Dreams Wind