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) {
...
}
};
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.