Search code examples
c++c++11stdnumeric-limits

Difference between std::is_signed<T> and std::numeric_limits<T>::is_signed?


Both std::is_signed<T> and std::numeric_limits<T>::is_signed are supposed to give answers about the signedness of T.
Why are there now two indicators for signedness (i.e. since C++11)?


Solution

  • I'm going to hazard a guess that the only difference is if std::numeric_limits<T> is specialized for a user-defined type. Such a user-defined type could of course provide their own value for is_signed. But asking for std::is_signed<T>::value on this type will always return false unless std::is_signed<T> has been independently specialized.

    It seems as though the condition that std::is_signed<T> represents is

    is_arithmetic<T>::value && T(-1) < T(0)
    

    Update: The always-knowledgable Howard Hinnant points out that while std::numeric_limits<> can be legally-specialized, nothing in <type_traits> is allowed to be specialized unless otherwise specified, and is_signed is not specified as being specializable.

    Therefore, std::numeric_limits<T>::is_signed may return true for a user-defined type (if it's been specialized) but std::is_signed<T>::value will always return false for user-defined types.