With SFINAE you can enable/disable a method of a class when the condition tested is related to a template parameter of the method itself. Doesn't works testing a template parameter of the class.
You can solve the problem passing through a method template parameter that is defaulted with the type of the class/struct template parameter.
For example
#include <iostream>
#include <type_traits>
template <typename T>
struct foo
{
template <typename U = T,
std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
{ return sizeof(T); }
};
int main()
{
foo<signed int> fs;
foo<unsigned int> fu;
fs.bar(); // compile
//fu.bar(); // compilation error
}
The problem of this solution is that you can "hijack" it explicating a template parameter
fu.bar(); // compilation error
fu.bar<int>(); // compile
To avoid the hijacking risk, you can (other solutions are possible but this is my preferred) add a non-type variadic template parameter before U
// .......VVVVVVVV add this to avoid the hijacking problem
template <int ...,
typename U = T,
std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
{ return sizeof(T); }
// ...
fu.bar(); // compilation error
fu.bar<int>(); // compilation error
fu.bar<1, 2, 3, int>(); // compilation error
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…