Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining if ::std::numeric_limits<T> is safe to instantiate

The class template ::std::numeric_limits<T> may only be instantiated for types T, which can be the return value of functions, since it always defines member functions like static constexpr T min() noexcept { return T(); } (see http://www.cplusplus.com/reference/limits/numeric_limits/ for more information of the non-specialised versions in c++03 or c++11).

If T is i.e. int[2] the instantiation will immediately lead to a compile time error, since int[2] cannot be the return value of a function.

Wrapping ::std::numeric_limits with a safe version is easy - if a way to determine if it is safe to instantiate ::std::numeric_limits is known. This is necessary, since the problematic functions should be accessible if possible.

The obvious (and obviously wrong) way of testing ::std::numeric_limits<T>::is_specialised does not work since it requires instantiation of the problematic class template.

Is there a way to test for safety of instantiation, preferably without enumerating all known bad types? Maybe even a general technique to determine if any class template instantiation is safe?

like image 507
gha.st Avatar asked May 12 '13 09:05

gha.st


1 Answers

Concerning the type trait that decides whether a type can be returned for a function, here is how I would go about it:

#include <type_traits>

template<typename T, typename = void>
struct can_be_returned_from_function : std::false_type { };

template<typename T>
struct can_be_returned_from_function<T,
    typename std::enable_if<!std::is_abstract<T>::value,
    decltype(std::declval<T()>(), (void)0)>::type>
    : std::true_type { };

On the other hand, as suggested by Tom Knapen in the comments, you may want to use the std::is_arithmetic standard type trait to determine whether you can specialize numeric_limits for a certain type.

Per paragraph 18.3.2.1/2 of the C++11 Standard on the numeric_limits class template, in fact:

Specializations shall be provided for each arithmetic type, both floating point and integer, including bool. The member is_specialized shall be true for all such specializations of numeric_limits.

like image 156
Andy Prowl Avatar answered Sep 23 '22 03:09

Andy Prowl