Почему div, ldiv и lldiv не являются шаблонами?

В соответствии с этот, имеются

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 );

два див в <cinttypes>

Я бы предпочел видеть

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

Мысли?

0

Решение

Вы имеете в виду, что вы хотели бы использовать шаблонные специализации вместо перегрузки? Это не очень хорошая идея.

Прежде всего, что если я использую тип, у которого есть оператор преобразования в long? Ну, ни одна из специализаций не будет выбрана, потому что они берутся только тогда, когда есть точное совпадение, и этот тип не является их частью. Поэтому я должен использовать static_cast, Это не относится к перегрузке операторов, когда такое преобразование разрешено и будет иметь место.

Во-вторых, какое преимущество вы получаете от такой специализации? Вы все еще должны написать ту же реализацию для каждой специализации. Кроме того, вы не можете легко написать реализацию в исходном файле.

Единственное преимущество, которое я мог видеть, состоит в том, что гораздо проще получить адрес конкретной версии функции, как с шаблонами, которые вы сделали бы. &std::div<int> вместо static_castв правильную перегрузку.

Здесь общее решение было бы гораздо более уместным, потому что между этими функциями есть некоторое дублирование. Может быть, что-то вроде этого:

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};
}
2

Другие решения

Других решений пока нет …