Я не понимаю 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 :: stable_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
Вы правильно определили проблему. Ты можешь использовать 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
Указывая, что сумма nanoseconds
а также NTSC_FPS_t
имеет единицы 1/3 наносекунды.
Других решений пока нет …