- Есть ли более легкий доступ к
арифметические средства что
duration
и time_point
определяют в
<chrono>
в любом случае? Могу ли я использовать эти
уменьшить усилие на Length
?
Для арифметики "смешанного режима" и сравнений вы можете воспользоваться common_type<T1, T2>::type
для определения типов возвращаемых значений. duration
специализирует common_type
как наибольший общий делитель Period1 и Period2, где Period1 и Period2 являются двумя ratio
, участвующими в операции арифметики или сравнения. Вы можете использовать это как:
template <typename Scale1, typename Scale2>
typename std::common_type<Length<Scale1>, Length<Scale2>>::type
operator+(Length<Scale1> x, Length<Scale2> y);
К сожалению, вам придется заново изобрести, как получить наибольший общий делитель двух ratio
с во время компиляции. Начните с мета-функций gcd и lcm времени компиляции для unsigned long long.
Хм ... или вы могли бы основать свою специализацию common_type
на уже сделанной для duration
. Вы можете переосмыслить результирующий duration
period
как масштабный коэффициент для вашего Length
. Я не прототипировал это, просто идея.
- Постоянная времени компиляции
(Scale2::num*Scale::den)/(Scale2::den*Scale::num)
кажется опасным в преобразовании
конструктор (дробь / недополнение?),
но я не могу понять лучше
способ метапрограммирования, есть здесь какие-то подсказки?
Согласовано. duration
обрабатывает это с помощью:
template <class Rep2, class Period2>
constexpr duration(const duration<Rep2, Period2>& d);
Замечания: Этот конструктор не должен
участвовать в разрешении перегрузки
если treat_as_floating_point<rep>::value
не верно или оба
ratio_divide<Period2, period>::den
есть
1 и treat_as_floating_point<Rep2>::value
ложно.
[ Примечание: Это требование предотвращает
неявная ошибка усечения при
преобразование между интегральными
типы продолжительности. Такая конструкция
может легко привести к путанице
значение продолжительности. - конечная нота ]
т.е. вам нужно enable_if
ваш Length
конструктор преобразования так, чтобы он существовал, только если преобразование является точным (если вы хотите основывать свою длину на целочисленных типах). Чтобы преобразование было точным, коэффициент преобразования (Scale2::num*Scale::den)/(Scale2::den*Scale::num)
должен быть вычисляемым без деления (кроме деления на 1). Вы можете использовать ratio_divide
, чтобы сделать это деление для вас, и тогда полученный знаменатель должен быть 1 (для точного преобразования).
enable_if<ratio_divide<Scale2, Scale1>::type::den == 1, ...>
Это отличный проект для изучения ratio
! Повеселись! : -)