比率数学不能用于std :: chrono :: duration

时间:2017-11-01 20:54:02

标签: c++ chrono

我不明白std::chrono::duration

我正在尝试根据视频帧速率计算未来的时间点。一旦达到该时间点,我需要再次(并再次)做同样的事情。

像这样:

#include <chrono>
using namespace std::chrono;
typedef duration<int, std::ratio<1,10>> TenFPS_t;
typedef duration<int, std::ratio<1001,30000>> NTSC_FPS_t;
// this compiles ok
time_point<steady_clock> compiles (time_point<steady_clock>& ref, int frames) {
return ref + TenFPS_t(frames);
}
// this one, when uncommented spits out many complaints
time_point<steady_clock> wontCompile (time_point<steady_clock>& ref, int frames) {
return ref + NTSC_FPS_t(frames);
}

我想问题是30,000 / 1,001不是纳秒的整数,这是(我认为)我正在使用的std::chrono::steady_clock的分辨率。所以我需要在帧周期中选择最接近的整数并累积误差以输入下一个的计算。我是对的吗?

编译器错误如下:

$ g++ -Wall -ggdb -std=gnu++0x -fPIC example.cpp  -c -o example.o
example.cpp:12:9: error: no viable conversion from returned value of type
      'time_point<[...], duration<[...], ratio<[...], __static_lcm<ratio<1,
      1000000000>::den, ratio<1001, 24000>::den>::value aka 3000000000>>>' to
      function return type 'time_point<[...], duration<[...], ratio<[...],
      1000000000>>>'
        return ref + NTSC_FPS_t(frames);
               ^~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/chrono:831:28: note: 
      candidate constructor (the implicit copy constructor) not viable: no known
      conversion from 'time_point<std::__1::chrono::steady_clock, typename
      common_type<duration<long long, ratio<1, 1000000000> >, duration<int,
      ratio<1001, 24000> > >::type>' (aka
      'time_point<std::__1::chrono::steady_clock, duration<long long,
      ratio<__static_gcd<ratio<1, 1000000000>::num, ratio<1001,
      24000>::num>::value, __static_lcm<ratio<1, 1000000000>::den, ratio<1001,
      24000>::den>::value> > >') to 'const
      std::__1::chrono::time_point<std::__1::chrono::steady_clock,
      std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000000> > >
      &' for 1st argument
class _LIBCPP_TEMPLATE_VIS time_point
                           ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/chrono:831:28: note: 
      candidate constructor (the implicit move constructor) not viable: no known
      conversion from 'time_point<std::__1::chrono::steady_clock, typename
      common_type<duration<long long, ratio<1, 1000000000> >, duration<int,
      ratio<1001, 24000> > >::type>' (aka
      'time_point<std::__1::chrono::steady_clock, duration<long long,
      ratio<__static_gcd<ratio<1, 1000000000>::num, ratio<1001,
      24000>::num>::value, __static_lcm<ratio<1, 1000000000>::den, ratio<1001,
      24000>::den>::value> > >') to
      'std::__1::chrono::time_point<std::__1::chrono::steady_clock,
      std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000000> > >
      &&' for 1st argument
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/chrono:853:13: note: 
      candidate template ignored: disabled by 'enable_if' [with _Duration2 =
      std::__1::chrono::duration<long long, std::__1::ratio<1, 3000000000> >]
            is_convertible<_Duration2, duration>::value
            ^
1 error generated.
L-REMJNAYLOR:poc jnaylor$ g++ -Wall -ggdb -std=gnu++0x -fPIC example.cpp  -c -o example.o
example.cpp:12:9: error: no viable conversion from returned value of type
      'time_point<[...], duration<[...], ratio<[...], __static_lcm<ratio<1,
      1000000000>::den, ratio<1001, 30000>::den>::value aka 3000000000>>>' to
      function return type 'time_point<[...], duration<[...], ratio<[...],
      1000000000>>>'
        return ref + NTSC_FPS_t(frames);
               ^~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/chrono:831:28: note: 
      candidate constructor (the implicit copy constructor) not viable: no known
      conversion from 'time_point<std::__1::chrono::steady_clock, typename
      common_type<duration<long long, ratio<1, 1000000000> >, duration<int,
      ratio<1001, 30000> > >::type>' (aka
      'time_point<std::__1::chrono::steady_clock, duration<long long,
      ratio<__static_gcd<ratio<1, 1000000000>::num, ratio<1001,
      30000>::num>::value, __static_lcm<ratio<1, 1000000000>::den, ratio<1001,
      30000>::den>::value> > >') to 'const
      std::__1::chrono::time_point<std::__1::chrono::steady_clock,
      std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000000> > >
      &' for 1st argument
class _LIBCPP_TEMPLATE_VIS time_point
                           ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/chrono:831:28: note: 
      candidate constructor (the implicit move constructor) not viable: no known
      conversion from 'time_point<std::__1::chrono::steady_clock, typename
      common_type<duration<long long, ratio<1, 1000000000> >, duration<int,
      ratio<1001, 30000> > >::type>' (aka
      'time_point<std::__1::chrono::steady_clock, duration<long long,
      ratio<__static_gcd<ratio<1, 1000000000>::num, ratio<1001,
      30000>::num>::value, __static_lcm<ratio<1, 1000000000>::den, ratio<1001,
      30000>::den>::value> > >') to
      'std::__1::chrono::time_point<std::__1::chrono::steady_clock,
      std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000000> > >
      &&' for 1st argument
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/chrono:853:13: note: 
      candidate template ignored: disabled by 'enable_if' [with _Duration2 =
      std::__1::chrono::duration<long long, std::__1::ratio<1, 3000000000> >]
            is_convertible<_Duration2, duration>::value
            ^
1 error generated

1 个答案:

答案 0 :(得分:3)

您已正确识别问题。您可以使用return time_point_cast<steady_clock::duration>(ref + NTSC_FPS_t(frames));,它将向下截断steady_clock::duration(纳秒)。

在C ++ 17中,您将拥有其他舍入模式:

  • floor
  • ceil
  • round

如果你想在C ++ 17之前使用它们,欢迎你在这里使用它们:https://github.com/HowardHinnant/date/blob/master/include/date/date.h

如果有帮助,请参阅<chrono>的视频教程:https://www.youtube.com/watch?v=P32hvk8b13M

你也可以使用"date.h"来探索的结果来自steady_clock::time_point + NTSC_FPS_t,如下所示:

#include "date/date.h"
#include <iostream>

typedef std::chrono::duration<int, std::ratio<1001,30000>> NTSC_FPS_t;

int
main()
{
    using date::operator<<;
    auto tp = std::chrono::steady_clock::now() + NTSC_FPS_t{1};
    std::cout << tp.time_since_epoch() << '\n';
}

对我来说这只是输出:

4680675375035054[1/3000000000]s

表示nanosecondsNTSC_FPS_t之和的单位为 1 / 3 。纳秒。