【问题标题】:Why are div, ldiv and lldiv not templates?为什么 div、ldiv 和 lldiv 不是模板?
【发布时间】:2017-07-09 00:41:12
【问题描述】:

根据this,有

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> 中的两个 div

我更愿意看到

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

想法?

【问题讨论】:

  • 最后的std::div&lt;int&gt;应该是std::div_t&lt;int&gt;吧?
  • 真正让我困惑的是这些函数的存在——是的,除法和模数通常在硬件级别一起计算,但我所知道的几乎任何生产就绪的编译器都已经能够利用这个事实并且如果 C 代码同时执行除法和取模,则只执行一次计算。
  • @MatteoItalia:“我所知道的几乎所有生产就绪的编译器”你知道二十年来“生产就绪的编译器”的状态吗?我>以前?因为这些是 C++98 函数。我宁愿怀疑当时的编译器质量完全不同。
  • 很公平。我实际上不知道它们曾经存在过,所以我认为它们是最近添加的,因此我很困惑。

标签: c++ cmath c++20


【解决方案1】:

你的意思是你想使用模板特化而不是重载?这不是一个好主意。

首先,如果我使用具有long 的转换运算符的类型怎么办?好吧,不会选择任何专业化,因为它们仅在完全匹配时才会被采用,并且该类型不属于它们的一部分。所以我必须使用static_cast。这不是运算符重载的情况,在这种情况下允许并且会发生这种转换。

其次,通过这样的专业化你能获得什么优势?您仍然必须为每个专业化编写相同的实现。此外,您不能轻易将实现写在源文件中。

我能看到的唯一优势是获取特定版本函数的地址要容易得多,就像使用模板一样,您可以使用 &amp;std::div&lt;int&gt; 而不是 static_casting 来正确重载。

这里使用通用解决方案会更合适,因为这些功能之间存在一些重复。也许是这样的:

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

【讨论】:

  • concept bool 已过时;只需使用concept
  • @Yakk 不错!感谢您的信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 2019-01-25
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 2022-08-10
相关资源
最近更新 更多