This happens because if you take a look inside std::numeric_limits
or take a look at the documentation you will see declarations of methods like the following
template<class T>
class numeric_limits
{
public:
static constexpr bool is_specialized = false;
static constexpr T min() noexcept;
static constexpr T max() noexcept;
static constexpr T lowest() noexcept;
Here as you can see there are functions that return T
by value, and C++ does not support returning array types by value (see Why doesn't C++ support functions returning arrays?)
So the following line will not compile
std::numeric_limits<char[20]>::is_specialized
And any further attempt to directly check whether is_specialized
works for a type directly with SFINAE will not compile because there will be an error produced (because of returning array types as explained above) that is not in the immediate context of the template. So you would need to inspect the concept that is supported for std::numeric_limits
(in this case std::is_arithmetic
)
However all you need to do here to make this work is to std::decay_t
the type
std::numeric_limits<std::decay_t<char[20]>>::is_specialized
And now it will work because you have explicitly decayed the array type into a pointer and that is returnable from the function. You probably wanted to do that in the first place because you don't want to accidentally call std::numeric_limits::is_specialized
for a non decayed type like const int&
char[20]
, for which we all know the answer? – Tennestatic_assert
is, indeed, to issue a compilation error if the assertion fails. If you need a different result, you have to explain what it is. – Cassidycassie