Search code examples
c++cmathc++20

Why are div, ldiv and lldiv not templates?


According to this, there are

std::div_t     div( int x, int y );
std::ldiv_t    div( long x, long y );
std::lldiv_t   div( long long x, long long y );
std::ldiv_t   ldiv( long x, long y );
std::lldiv_t lldiv( long long x, long long y );

two div in <cinttypes>

I would prefer to have seen

template<typename t>
std::div_t<T> div(T x, T y);
template<>
std::div_t<int> div(int x, int x)
{
  // implementation here
}

Thoughts?


Solution

  • You mean you would like to use template specializations instead of overloading? That's not a good idea.

    First of all, what if I use a type that has a conversion operator to long? Well, none of the specialization is going to get chosen, because they are only taken when there is an exact match, and that type is not part of them. So I have to use a static_cast. This is not the case with operator overloading, where such a conversion is allowed and will happen.

    Second of all, what advantage do you gain by specializing like that? You still have to write the same implementation for each specialization. In addition, you can't easily write the implementation in a source file.

    The only advantage I could see is that it is much easier to take the address of a specific version of the function, as with templates you would do &std::div<int> instead of static_casting to the right overload.

    Here a generic solution would be much more appropriate, because there is some duplication between those functions. Maybe something like this:

    template<typename T>
    concept Integral = std::is_integral_v<T>;
    
    template <Integral T>
    struct cdiv_t {
        T quot{};
        T rem{};
    };
    
    constexpr auto cdiv(Integral auto x, Integral auto y) noexcept {
        return cdiv_t{x / y, x % y};
    }