C++中如何对std::chrono::duration进行扩展?

3

我不理解如何扩展std::chrono::duration。以浮点数为因子,将持续时间扩展的正确方式是什么?

template <class Duration>
auto random_duration(Duration low, Duration high) noexcept -> Duration {
    static auto rd = std::random_device();
    static auto re = std::default_random_engine(rd());
    auto dist = std::uniform_real_distribution<double>(0, 1);
    const auto off = std::chrono::duration<Duration>(dist(re) * (high - low));
    return low + off;
}

2
你的代码有什么问题吗?你确实将持续时间按随机因素进行了缩放,对吧? - 463035818_is_not_a_number
3
请在问题中包含编译器错误,并提供一个 [mcve]。 - 463035818_is_not_a_number
2
@lubgr 抱歉,我没有看到 OP 想要返回一个 Duration,这很奇怪... 如果删除 std::chrono::duration<Duration> 和显式的返回类型,你将得到一个自动返回类型,这可能是你想要的。强制转换为 Duration 将会失去很多精度,这可能不是你想要的。 - Holt
2
风格指南1:此函数的模板参数过于通用。它接受任何类型。将其模板化为“Rep”和“Period”,并将参数设置为“duration<Rep,Period>”。 - Howard Hinnant
2
样式指南2:此函数不必要地限制了两个持续时间参数具有相同的单位。让它们不同:template <class Rep1, class Period1, class Rep2, class Period2> auto random_duration(duration<Rep1, Period1>, duration<Rep2, Period2>) - Howard Hinnant
显示剩余8条评论
1个回答

3
首先,如果你使用两个 std::duration<double, ...> 对象实例化此模板,则一切正常且符合预期。你遇到的问题可能是通过 operator* 得到的实例在输入类型为像 std::duration<int, ...> 的情况下可能无法隐式转换为尾返回类型(Duration)。在这种情况下,将其缩放为双精度浮点数是一个有损操作,如果你打算这样做,那么就没问题,但将其作为 Duration 返回是不行的。除非你显式地指定,否则 <chrono> 不允许这样的转换,这是一件好事。
以下是它可以工作的方式。
const auto off = dist(re)*((high - low));

return low + std::chrono::duration_cast<Duration>(off);

因此,您需要明确地将输入持续时间进行可能有损转换,以使其可以乘以 double。一旦完成此步骤,为了符合尾部返回类型 Duration,您需要明确地将其转换回来。


1
std::chrono::seconds d1(10); auto d2 = 2.5 * d1; 尽管 secondsRep 类型是整数,但这对我来说是可以编译的。 - Daniel Langr
2
Cppreference 对 operator* 的解释是:将持续时间 d 转换为其 repRep1Rep2公共类型,并在转换后将滴答数乘以 s - Daniel Langr
3
好的,我明白了。您在上面的wandbox链接中获取的auto d2是一个std::duration<double>,这是由于common_type模板确定了operator的返回类型。问题在于该返回类型作为_原始_表示形式存在丢失转换。 - lubgr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接