当我们有 conexpr 值时 <ratio> 有什么用?
What's the use of <ratio> when we have contexpr values?
<ratio>
header 允许您使用模板 meta-programming 来处理和操作 rational 值。
然而 - 它是在 C++11 中引入的,当时我们已经有了 constexpr
。为什么有一个 fully-constexpr'ifed 库类型用于有理数还不够好,即基本上:
template<typename I>
struct rational {
I numerator;
I denominator;
};
然后改用它?
使用 C++11 constexpr 功能 well-suited 还不够的 std::ratio
是否有一些具体的好处?如果是这样,它在 C++20 中是否仍然相关(constexpr 的扩展“范围”)?
Is there some concrete benefit to using std::ratio that C++11 constexpr functionality would not be well-suited enough for?
您可以将 ratio
作为模板类型参数传递,这就是 std::chrono::duration
的作用。要以 value-based 比率做到这一点,您需要 C++20 或更新版本。
在 C++20 和更新版本中,我看不到当前设计的任何好处。
这里有几个答案和评论,但我认为其中 none 真正说明了 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;
};
用一堆 constexpr
函数来执行该类型的算术运算。
请注意,这两个定义之间存在细微但非常重要的区别。而在第二个中,比率的实际值(num
和 den
)存储在类型的 实例 中,而在第一个定义中,值是实际上存储在 type 本身。
如果你有一个像 std::chrono
这样的库,你想要一个类型,它可以将时间存储为毫秒数(例如 std::chrono::milliseconds
)。如果您稍后想要将此数字转换为秒,则您不想将转换比率编码到 std::chrono::milliseconds
的实例中,而是编码到类型本身中。这就是为什么 std::chrono
使用第一种形式而不是第二种形式(或简单的浮点值)的原因。
要将数字存储到类型而不是实例中,您需要 non-type template parameter。在 C++20 之前,您只能为 non-type 模板参数使用整数值。尽管如此,为了将合理的转换因子存储在标准库中,指定了 std::ratio
class 模板。
在 C++20 中,潮流发生了一点变化,因为您现在可以使用浮点数作为 non-type 模板参数。例如 std::chrono::duration
可以重写为:
template<..., double conversion_factor, ...>
duration {
...
};
此 C++20 功能与“constexpr 的扩展范围”无关
你在问题中提到的。编译时间计算不同于在类型本身中存储数值,尽管你需要第一个来做第二个。
使用 std::ratio
class 模板(专门)用于将值存储到类型中。
boost::rational
was provided about the same time as boost::ratio
. However since the later was used by boost::chrono
which was in turn used by boost::thread
, it was easier to add the whole bunch together to the standard. If one seeks a full-fledged run-time usable rational number class, boost::rational
is there. The boost::multiprecision
is also available to provide very long integral types as the argument for boost::rational
. Regarding the standardization of other parts of boost such as boost::random
, it has been a big question to me why boost::rational
尚未添加到标准库中。
此致,
调频
<ratio>
header 允许您使用模板 meta-programming 来处理和操作 rational 值。
然而 - 它是在 C++11 中引入的,当时我们已经有了 constexpr
。为什么有一个 fully-constexpr'ifed 库类型用于有理数还不够好,即基本上:
template<typename I>
struct rational {
I numerator;
I denominator;
};
然后改用它?
使用 C++11 constexpr 功能 well-suited 还不够的 std::ratio
是否有一些具体的好处?如果是这样,它在 C++20 中是否仍然相关(constexpr 的扩展“范围”)?
Is there some concrete benefit to using std::ratio that C++11 constexpr functionality would not be well-suited enough for?
您可以将 ratio
作为模板类型参数传递,这就是 std::chrono::duration
的作用。要以 value-based 比率做到这一点,您需要 C++20 或更新版本。
在 C++20 和更新版本中,我看不到当前设计的任何好处。
这里有几个答案和评论,但我认为其中 none 真正说明了 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;
};
用一堆 constexpr
函数来执行该类型的算术运算。
请注意,这两个定义之间存在细微但非常重要的区别。而在第二个中,比率的实际值(num
和 den
)存储在类型的 实例 中,而在第一个定义中,值是实际上存储在 type 本身。
如果你有一个像 std::chrono
这样的库,你想要一个类型,它可以将时间存储为毫秒数(例如 std::chrono::milliseconds
)。如果您稍后想要将此数字转换为秒,则您不想将转换比率编码到 std::chrono::milliseconds
的实例中,而是编码到类型本身中。这就是为什么 std::chrono
使用第一种形式而不是第二种形式(或简单的浮点值)的原因。
要将数字存储到类型而不是实例中,您需要 non-type template parameter。在 C++20 之前,您只能为 non-type 模板参数使用整数值。尽管如此,为了将合理的转换因子存储在标准库中,指定了 std::ratio
class 模板。
在 C++20 中,潮流发生了一点变化,因为您现在可以使用浮点数作为 non-type 模板参数。例如 std::chrono::duration
可以重写为:
template<..., double conversion_factor, ...>
duration {
...
};
此 C++20 功能与“constexpr 的扩展范围”无关 你在问题中提到的。编译时间计算不同于在类型本身中存储数值,尽管你需要第一个来做第二个。
使用 std::ratio
class 模板(专门)用于将值存储到类型中。
boost::rational
was provided about the same time as boost::ratio
. However since the later was used by boost::chrono
which was in turn used by boost::thread
, it was easier to add the whole bunch together to the standard. If one seeks a full-fledged run-time usable rational number class, boost::rational
is there. The boost::multiprecision
is also available to provide very long integral types as the argument for boost::rational
. Regarding the standardization of other parts of boost such as boost::random
, it has been a big question to me why boost::rational
尚未添加到标准库中。
此致, 调频