C++ 为什么div、ldiv和lldiv不是模板?

C++ 为什么div、ldiv和lldiv不是模板?,c++,cmath,c++20,C++,Cmath,C++20,据报道,有 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 ); 我宁愿去看看 template<typename t>

据报道,有

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

我宁愿去看看

template<typename t>
std::div_t<T> div(T x, T y);
template<>
std::div_t<int> div(int x, int x)
{
  // implementation here
}
模板
标准:div_t div(tx,ty);
模板
标准::div_t div(整数x,整数x)
{
//在这里实现
}

想法?

您的意思是希望使用模板专门化而不是重载?那不是个好主意

首先,如果我使用一个类型,该类型有一个到
long
的转换运算符,该怎么办?好吧,没有一个专业是会被选择的,因为它们只有在有精确匹配的情况下才会被采用,而这种类型不是它们的一部分。因此,我必须使用
静态\u cast
。运算符重载不是这种情况,在这种情况下,允许并将发生这种转换

第二,你这样专攻有什么好处?您仍然必须为每个专门化编写相同的实现。此外,您无法在源文件中轻松编写实现

我所能看到的唯一优势是,获取函数的特定版本的地址要容易得多,就像使用模板一样,您可以使用
&std::div
而不是
static\u 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};
}
模板
概念积分=std::is_Integral_v;
模板
结构cdiv\u t{
T quot{};
T rem{};
};
constexpr自动cdiv(积分自动x、积分自动y)无例外{
返回cdiv_t{x/y,x%y};
}

您的意思是希望使用模板专门化而不是重载?那不是个好主意

首先,如果我使用一个类型,该类型有一个到
long
的转换运算符,该怎么办?好吧,没有一个专业是会被选择的,因为它们只有在有精确匹配的情况下才会被采用,而这种类型不是它们的一部分。因此,我必须使用
静态\u cast
。运算符重载不是这种情况,在这种情况下,允许并将发生这种转换

第二,你这样专攻有什么好处?您仍然必须为每个专门化编写相同的实现。此外,您无法在源文件中轻松编写实现

我所能看到的唯一优势是,获取函数的特定版本的地址要容易得多,就像使用模板一样,您可以使用
&std::div
而不是
static\u 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};
}
模板
概念积分=std::is_Integral_v;
模板
结构cdiv\u t{
T quot{};
T rem{};
};
constexpr自动cdiv(积分自动x、积分自动y)无例外{
返回cdiv_t{x/y,x%y};
}

最后的
std::div
应该是
std::div\t
,对吗?实际上让我困惑的是这些函数的存在-是的,除法和模通常在硬件级别一起计算,但实际上,我所知道的任何生产型编译器都已经能够利用这一事实,如果C代码同时执行除法和模运算,则只需执行一次计算。@MatteoItalia:“我所知道的几乎所有生产型编译器”您知道二十年前“生产型编译器”的状态吗?因为这些都是C++98函数。我相当怀疑编译器的质量在当时是完全不同的。这很公平。实际上我不知道它们曾经存在过,所以我认为它们是最近添加的,因此我感到困惑。最终的
std::div
应该是
std::div\u t
,对吗?真正让我困惑的是这些函数的存在-是的,除法和模法通常在硬件级别一起计算,但实际上,我所知道的任何生产型编译器都已经能够利用这一事实,如果C代码同时执行除法和模运算,则只需执行一次计算。@MatteoItalia:“我所知道的几乎所有生产型编译器”您知道二十年前“生产型编译器”的状态吗?因为这些都是C++98函数。我相当怀疑编译器的质量在当时是完全不同的。这很公平。事实上,我并不知道它们曾经存在过,所以我认为它们是最近添加的,因此我感到困惑。
概念bool
已经过时;只要使用
概念
@yaknice!感谢您提供的信息
概念bool
已过时;只要使用
概念
@yaknice!谢谢你的信息