Why doesn't the following code compile and what is the most concise solution for enabling templates for types with particular members? Also it compiles if template variable is replaced with an expression, which is used to initialize it, directly.
#include <iostream>
template<class T>
constexpr bool is_rect = std::is_same_v<decltype(T::left, T::top, T::right, T::bottom, void()), void>;
// compiles if is_rect<T> is replaced with the expression directly, but of course it's not a solution
template<class T, std::enable_if_t<is_rect<T>, int> = 0>
void f(T)
{
std::cout << "rect enabled\n";
}
template<class T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
void f(T)
{
std::cout << "arithmetic enabled\n";
}
struct ActualType { float left, top, right, bottom; };
int main()
{
f(ActualType{});
f(int{});
return 0;
}