I want to check to see if a type has an entry in std::numeric_limits. When the type is an array - (or perhaps not a number?) I get a compiler error. This prevents me from detecting and branching based on whether the type is supported in std::numeric_limits. I would appreciate any insight anyone wants to share.
// the following provokes compiler error on Clang
// Function cannot return array type 'type' (aka 'char [20]')
static_assert(
! std::numeric_limits<char[20]>::is_specialized,
"! std::numeric_limits<char[20]>::is_specialized"
);
// invokes static assert on compile as expected
static_assert(
std::numeric_limits<char[20]>::is_specialized,
"std::numeric_limits<char[20]>::is_specialized"
);
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&
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With