I wanted to do the division while obtaining the private and the remainder as follows:

auto result = std::div (a, b); // тип a и b - std::size_t 

But in c ++ there is no version of std :: div for arguments of type std :: size_t, and I need this type for greater portability. There is an ambiguity when calling std :: div, because c ++ does not know which type to convert std :: size_t to - int, long or long long.

Maybe someone will tell you how best to perform the division, requesting ambiguity and not losing portability?

    2 answers 2

    From the GNU libc source:

     /* Return the `div_t' representation of NUMER over DENOM. */ div_t div (numer, denom) int numer, denom; { div_t result; result.quot = numer / denom; result.rem = numer % denom; return result; } 

    So do not worry. Because you have unsigned variables, you can simplify:

     result.quot = numer / denom; result.rem = numer - denom * result.quot; 
    • Thank you, you are right. True, you took the source from the C-shnoy library, but it turned out in C ++ - the same thing. - Komandor 4:19 pm

    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.

    • Ehm Custs in signed can truncate value. - VladD
    • @VladD, of course it can. But since the author tried to stuff size_t into std::div this should suit him. - ixSci
    • On the other hand, what if the TC has a qualification lower than yours? And he did not think. :) - VladD
    • @VladD, I always think of people in a positive way :) However, I added verification and an alternative solution to the issue. - ixSci
    • I just thought that the div was somehow optimally constructed, and since it still performs the / and%, I don’t need it. But I just need size_t :) - komandor