Another option. If there is support for C ++ 14 in the compiler, then we write a simple wrapper:
template<typename T> auto Div(T a, T b) { using Signed_t = typename std::make_signed<T>::type; auto max = static_cast<T>(std::numeric_limits<Signed_t>::max); assert(a <= max && b <= max); return std::div(static_cast<Signed_t>(a), static_cast<Signed_t>(b)); }
If there is only C ++ 11 support, then the wrapper will be a bit worse:
template<typename T> auto Div(T a, T b) -> decltype(std::div(static_cast<typename std::make_signed<T>::type>(a), static_cast<typename std::make_signed<T>::type>(b))) { using Signed_t = typename std::make_signed<T>::type; auto max = static_cast<T>(std::numeric_limits<Signed_t>::max); assert(a <= max && b <= max); return std::div(static_cast<Signed_t>(a), static_cast<Signed_t>(b)); }
This option supports all 3 types that std::div can return and accepts all arguments that take std::div , including their unsigned pairs.
In general, the simplest and correct solution is to use ptrdiff_t instead of size_t . ptrdiff_t is the sign equivalent of size_t . With ptrdiff_t you can use std::div without problems.