将秒转换为std::chrono::duration

convert seconds as double to std::chrono::duration?

本文关键字:chrono duration std 转换      更新时间:2023-10-16

我使用的是c++11 <chrono>,秒数用双精度表示。我想使用c++11在这段时间内休眠,但我无法理解如何将它转换为std::this_thread::sleep_for所需的std::chrono::duration对象。

const double timeToSleep = GetTimeToSleep();
std::this_thread::sleep_for(std::chrono::seconds(timeToSleep));  // cannot convert from double to seconds

我已经锁定了<chrono>引用,但我发现它相当令人困惑。

感谢

编辑:

以下给出错误:

std::chrono::duration<double> duration(timeToSleep );
std::this_thread::sleep_for(duration);

错误:

c:program files (x86)microsoft visual studio 11.0vcincludechrono(749): error C2679: binary '+=' : no operator found which takes a right-hand operand of type 'const std::chrono::duration<double,std::ratio<0x01,0x01>>' (or there is no acceptable conversion)
2>          c:program files (x86)microsoft visual studio 11.0vcincludechrono(166): could be 'std::chrono::duration<__int64,std::nano> &std::chrono::duration<__int64,std::nano>::operator +=(const std::chrono::duration<__int64,std::nano> &)'
2>          while trying to match the argument list '(std::chrono::nanoseconds, const std::chrono::duration<double,std::ratio<0x01,0x01>>)'
2>          c:program files (x86)microsoft visual studio 11.0vcincludethread(164) : see reference to function template instantiation 'xtime std::_To_xtime<double,std::ratio<0x01,0x01>>(const std::chrono::duration<double,std::ratio<0x01,0x01>> &)' being compiled
2>          c:usersjohandesktopsvnjonsenginejonsenginesrcwindowglfwglfwwindow.cpp(73) : see reference to function template instantiation 'void std::this_thread::sleep_for<double,std::ratio<0x01,0x01>>(const std::chrono::duration<double,std::ratio<0x01,0x01>> &)' being compiled

不要执行std::chrono::seconds(timeToSleep)。你想要更像的东西

std::chrono::duration<double>(timeToSleep)

或者,如果timeToSleep不是以秒为单位测量的,则可以将比率作为模板参数传递给duration。有关更多信息,请参阅此处(以及那里的示例)。

让@Cornstars的答案更通用一点,你可以定义一个这样的函数:

template <typename T>
auto seconds_to_duration(T seconds) {
    return std::chrono::duration<T, std::ratio<1>>(seconds);
}

这将把任何基元类型的秒值转换为计时持续时间。这样使用:

const double timeToSleep = GetTimeToSleep();
std::this_thread_sleep_for(seconds_to_duration(timeToSleep));
const unsigned long timeToSleep = static_cast<unsigned long>( GetTimeToSleep() * 1000 );
std::this_thread::sleep_for(std::chrono::milliseconds(timeToSleep));

以上这些对我都不起作用。找到的有效解决方案是对另一个问题的回答:

从两秒到std::chrono::steady_clock::duration的Terse转换?

double period_in_seconds = 3.4;
auto as_duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(period_in_seconds));

这将double转换为std::chrono::steady_clock::duration

通常,使用标准时钟(如steady_clock)时,持续时间变量应始终为该时钟的成员类型,如std::chrono::steady_clock::duration

避免从模板中创建自己的工期类型,例如std::chrono::duration<double>,除非如上所示与duration_cast一起临时使用。

这使得与std::chrono::steady_clock::now()的时间比较最快,因为它避免了运行时不必要的转换,因为变量的持续时间类型已经与now()返回的time_point的持续时间匹配。

std::chrono::milliseconds duration(timeToSleep);
std::this_thread::sleep_for( duration );

您可以使用*operator重载将double转换为std::chrono::duration<double>,然后将其强制转换为所需的句点。

double start;
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>
    ( 
        std::chrono::seconds{1} * start
    );