<ratio> 当我们有 contexpr 值时有什么用?



<ratio>标头允许您使用模板元编程来处理和操纵有理值。

然而,它是在C++11中引入的,当时我们已经有了constexpr。为什么为推理提供一个完整的constexpr’fed库类型还不够好,即基本上:

template<typename I>
struct rational { 
I numerator;
I denominator;
};

然后用它来代替?

使用std::ratio是否有一些C++11 constexpr功能不太适合的具体好处?如果是这样的话,它在C++20中(随着constexpr的"reach"扩展(是否仍然相关?

使用std::ratio是否有一些具体的好处,而C++11 constexpr功能还不够适合?

您可以将ratio作为模板类型参数传递,std::chrono::duration就是这样做的。要使用基于值的比率,您需要C++20或更新版本。

在C++20和更新版本中,我看不到当前设计的任何好处。

这里有几个答案和评论,但我认为它们都没有真正说明std::ratio的意义。让我们从std::ratio的定义开始。大致相当于:

template<int Num, int Den>
struct ratio {
static constexpr int num = Num;
static constexpr int den = Den;
};

不过,您可能会使用以下内容作为std::ratio的替代方案:

template<typename I>
struct ratio {
I num;
I den;
};

用一堆CCD_ 9函数来执行该类型的运算。

请注意,这两个定义之间有一个微妙但非常重要的区别。而在第二个定义中,比率的实际值(numden(存储在类型的实例中,而在第一个定义中这些值实际上存储在类型本身中。

如果你有一个像std::chrono这样的库,你想要一个类型,它可以将时间存储为毫秒数(例如std::chrono::milliseconds(。如果以后要将此数字转换为秒,则不希望将转换比率编码到std::chrono::milliseconds的实例中,而希望将其编码到类型本身中。这就是std::chrono使用第一种形式而不是第二种形式(或简单的浮点值(的原因。

要将数字存储到类型而不是实例中,需要非类型模板参数。在C++20之前,您只能对非类型模板参数使用整数值。然而,为了存储合理的转换因子,标准库指定了std::ratio类模板。

在C++20中,趋势发生了一些变化,因为您现在可以使用浮点数字作为非类型模板参数。例如,std::chrono::duration可以重写为:

template<..., double conversion_factor, ...>
duration {
...
};

然而,这个C++20特性与"C"无关;constexpr的扩展范围;你在问题中提到的。编译时间计算不同于在类型本身中存储数值,尽管您需要第一个来执行第二个。

std::ratio类模板的使用(专门(用于将值存储到类型中。

boost::rationalboost::ratio大约在同一时间提供。然而,由于后者被boost::chrono使用,而boost::thread又使用了后者,因此更容易将整个束添加到标准中。如果寻找一个完整的运行时可用的有理数类,那么boost::rational就在那里。boost::multiprecision也可用于提供非常长的积分类型作为boost::rational的自变量。关于boost的其他部分,如boost::random的标准化,为什么boost::rational还没有添加到标准库中,这一直是我的一个大问题。

谨致问候,FM.

最新更新