std :: chrono :: длительность может быть инициализирована секундами, но не миллисекундами? - PullRequest
0 голосов
/ 26 сентября 2018

Работает: std::chrono::duration<unsigned long long> test1 = std::chrono::seconds(1);

Не работает: std::chrono::duration<unsigned long long> test2 = std::chrono::milliseconds(1);

Почему разница?Разве длительность не содержит достаточной степени детализации внутри?

Каков предпочтительный способ инициализации длительности из значения в миллисекундах?

1 Ответ

0 голосов
/ 26 сентября 2018
Список параметров шаблона

std::chrono::duration принимает два аргумента: тип для хранения базовых данных и аргумент std::ratio, представляющий экспоненту длительности.Типы, такие как std::chrono::seconds и std::chrono::milliseconds, являются специализациями этого шаблона и используют std::chrono::duration<int64_t, std::ratio<1>> и std::chrono::duration<int64_t, std::ratio<1, 1000>> соответственно.

Если вы не предоставите типу аргумент std::ratio, по умолчанию он будет равенstd::ratio<1>.

В результате ваш пользовательский тип длительности неявно принимает форму std::chrono::duration<unsigned long long, std::ratio<1>>, что делает его почти эквивалентным std::chrono::seconds (единственная разница заключается в значении без знака)вместо значения со знаком), но поскольку его отношение выше, чем отношение, предоставленное для std::chrono::milliseconds, шаблон класса запрещает преобразование присваивания / необработанного.В этом случае, если вы хотите, чтобы назначение прошло, вам нужно явно привести его:

typedef std::duration<unsigned long long> my_duration;
//my_duration test1 = std::chrono::milliseconds(1);//Forbidden
my_duration test1 = std::chrono::duration_cast<my_duration>(std::chrono::milliseconds(1)); //Permitted, will be truncated
my_duration test2 = std::chrono::duration_cast<my_duration>(1ms); //Permitted, may be easier to read

Параметр std::ratio представляет размер тика длительности.Чем меньше размер тика, тем больше будет базовое число, представляющее продолжительность.Как пример:

using seconds = std::chrono::seconds; //std::duration<int64_t, std::ratio<1,1>>
using milliseconds = std::chrono::milliseconds; //std::duration<int64_t, std::ratio<1,1000>>
using nanoseconds = std::chrono::nanoseconds; //std::duration<int64_t, std::ratio<1,1000000000>>

seconds time1 = 5s; //underlying integer value is 5.
milliseconds time2 = 5ms; //underlying integer value is 5.
time2 = time1; //underlying integer value for time2 is 5000, for time1 is still 5.
time2 = 17ms; //underlying integer value is 17.
//time1 = time2; //forbidden; tick size of time2 is smaller than time1
time1 = std::chrono::duration_cast<seconds>(time2); 
//underlying integer value for time1 is 0, due to truncation; time2 is still 17.
nanoseconds time3 = 5ms; //underlying integer value is 5000000.
time1 = 2s; //underlying integer value is 2.
time3 = time1; //underlying integer value is 2000000000.
...