gpt4 book ai didi

c++ - 在整数 std::chrono::durations 之间转换

转载 作者:行者123 更新时间:2023-11-30 04:46:58 25 4
gpt4 key购买 nike

我正在使用 std::chrono 编写标准游戏循环。我需要将一个 float 传递给我的渲染方法,它表示我进入下一帧的距离。为了计算我使用 chrono::duration 的 count() 方法的数字,因此我需要将两个持续时间转换为相同的比率。

void engine::run() {
using namespace std::chrono;
using updates = duration<steady_clock::rep, std::ratio<1, 40>>;
using common = std::common_type<updates, steady_clock::duration>::type;

constexpr updates time_per_update{1};
auto previous = steady_clock::now();
auto lag = steady_clock::duration::zero();

while (!quit) {
auto now = steady_clock::now();
auto delta = now - previous;

previous = now;
lag += delta;

while (lag >= time_per_update) {
lag -= time_per_update;
update(time_per_update);
}

render(common{lag}.count() / static_cast<double>(common{time_per_update}.count()));
}
}

如果我将“更新”中的比率更改为,比如说 41,我会在减法时遇到编译错误,因为 1/41 秒不能精确地转换为 steady_clock::duration。但是,当我将代码重写为这个时,它编译得很好:

void engine::run() {
using namespace std::chrono;
using updates = duration<steady_clock::rep, std::ratio<1, 41>>;
using common = std::common_type<updates, steady_clock::duration>::type;

constexpr common time_per_update{updates{1}};
auto previous = steady_clock::now();
common lag = steady_clock::duration::zero();

while (!quit) {
auto now = steady_clock::now();
auto delta = now - previous;

previous = now;
lag += delta;

while (lag >= time_per_update) {
lag -= time_per_update;
update(time_per_update);
}

render(lag.count() / static_cast<double>(time_per_update.count()));
}
}

我的印象是在减法过程中隐式地转换为 common_type。我错过了什么?有更好的方法吗?

最佳答案

澄清一下,这是出错的代码行:

 lag -= time_per_update;

test.cpp:27:11: error: no viable overloaded '-='
lag -= time_per_update;
~~~ ^ ~~~~~~~~~~~~~~~

I was under the impression the conversion to common_type happens implicitly during the subtraction.

你是对的,但不完全正确。

二元 减法运算符返回两个参数的common_type:

template <class Rep1, class Period1, class Rep2, class Period2>
constexpr
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);

但是 -= 运算符必须等效于:

lag = lag - delta;

如果 lag - deltaresult 不能隐式转换为 lag 的类型,那么你就有问题了(因为是你的例子的情况)。

lag 的类型更改为 common 是正确的解决方法:

common lag = steady_clock::duration::zero();

这是另一种方法。这两者之间的选择是风格上的:

auto lag = steady_clock::duration::zero() + updates{0};

最后,就我个人而言,我喜欢尽量减少(如果不是消除的话).count() 的使用,因为这相当于 reinterpret_cast 来自 durationintegral(或标量)。这在您的示例中并不难做到,并且不会降低效率。

首先添加一个等价于 common 的东西,它使用 double 作为表示:

using dcommon = duration<double, common::period>;

然后您只需将 lag 转换为 dcommon 并将其除以 time_per_update 即可得到您的比率:

render(dcommon{lag} / time_per_update);

最后,还有一种风格变化供您考虑:只需将 lag 表示为基于 double 的前端:

auto lag = steady_clock::duration::zero() + updates{0} + duration<double>{0};

现在您对 render 的调用更简单了:

render(lag / time_per_update);

commondcommon 甚至不再需要(您可以删除它们)。

关于c++ - 在整数 std::chrono::durations 之间转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56413121/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com