【问题标题】:convert seconds as double to std::chrono::duration?将秒数转换为 std::chrono::duration?
【发布时间】:2013-07-27 19:19:56
【问题描述】:

我正在使用 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.0\vc\include\chrono(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.0\vc\include\chrono(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.0\vc\include\thread(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:\users\johan\desktop\svn\jonsengine\jonsengine\src\window\glfw\glfwwindow.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

【问题讨论】:

  • Cornstalks 的回答是正确的。这看起来像 VS11 std::this_thread::sleep_for 中的一个错误。你可以尝试std::this_thread::sleep_for(std::chrono:duration_cast&lt;std::chrono::milliseconds&gt;(duration)) 来解决这个错误。我随意选择了毫秒。使用任何可行的方法,但让&lt;chrono&gt; 提供转化,而不是自己滚动。

标签: c++ c++11 chrono


【解决方案1】:

不要做std::chrono::seconds(timeToSleep)。你想要更多类似的东西:

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

或者,如果timeToSleep 不是以秒为单位,您可以将比率作为模板参数传递给duration。有关详细信息,请参阅 here(以及那里的示例)。

【讨论】:

    【解决方案2】:

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

    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));
    

    【讨论】:

      【解决方案3】:
      const unsigned long timeToSleep = static_cast<unsigned long>( GetTimeToSleep() * 1000 );
      std::this_thread::sleep_for(std::chrono::milliseconds(timeToSleep));
      

      【讨论】:

        【解决方案4】:
        std::chrono::milliseconds duration(timeToSleep);
        std::this_thread::sleep_for( duration );
        

        【讨论】:

        • 没有接受双精度的 chrono::milliseconds 构造函数。
        【解决方案5】:

        以上都不适合我。找到了工作解决方案作为对另一个问题的答案:

        Terse conversion from double seconds to std::chrono::steady_clock::duration?

        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&lt;double&gt;,除非如上所示临时使用duration_cast。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-28
          • 1970-01-01
          • 1970-01-01
          • 2016-07-20
          相关资源
          最近更新 更多