В соответствии с этот, имеются
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
}
Мысли?
Вы имеете в виду, что вы хотели бы использовать шаблонные специализации вместо перегрузки? Это не очень хорошая идея.
Прежде всего, что если я использую тип, у которого есть оператор преобразования в 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};
}
Других решений пока нет …