[C++] Hjälp mig förstå <chrono>:s templates
Har ett tag varit fascinerad över <chrono> och har försökt ta inspiration därifrån då jag i ett projekt inte har möjlighet att använda chrono direkt. Det verkar användas mycket kreativa templates som jag hoppas ni kan hjälpa mig få grepp på.
Som ni kanske känner till är <chrono> ett bibliotek för att hantera tid. Det jag kollat på nu är hur de gör för att göra aritmetik med olika typer. Då stötte jag på denna template för att överlagra vanlig addition:
https://github.com/microsoft/STL/blob/main/stl/inc/chrono#L30...
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
_NODISCARD constexpr common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>
operator+(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept(
is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ {
using _CD = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CD(_CD(_Left).count() + _CD(_Right).count());
}
_Rep1 och _Rep2 är då olika datatyper som används för att representera tidsenheter. På ett ställe kan man representera tid med int32_t och annanstans med uint64_t, chrono låter en då sömlöst addera dessa och verkar här automagiskt lösa vilken returtyp man får med sin common_type_t. Som jag förstått det iaf.
common_type_t hittas här:
https://github.com/microsoft/STL/blob/3a570ee597d1f1a49ab4233...
template <class... _Ty>
struct common_type;
template <class... _Ty>
using common_type_t = typename common_type<_Ty...>::type;
template <>
struct common_type<> {};
template <class _Ty1>
struct common_type<_Ty1> : common_type<_Ty1, _Ty1> {};
template <class _Ty1, class _Ty2, class _Decayed1 = decay_t<_Ty1>, class _Decayed2 = decay_t<_Ty2>>
struct _Common_type2 : common_type<_Decayed1, _Decayed2> {};
template <class _Ty1, class _Ty2>
struct _Common_type2<_Ty1, _Ty2, _Ty1, _Ty2> : _Decayed_cond_oper<_Ty1, _Ty2> {};
template <class _Ty1, class _Ty2>
struct common_type<_Ty1, _Ty2> : _Common_type2<_Ty1, _Ty2> {};
template <class _Void, class _Ty1, class _Ty2, class... _Rest>
struct _Common_type3 {};
template <class _Ty1, class _Ty2, class... _Rest>
struct _Common_type3<void_t<common_type_t<_Ty1, _Ty2>>, _Ty1, _Ty2, _Rest...>
: common_type<common_type_t<_Ty1, _Ty2>, _Rest...> {};
template <class _Ty1, class _Ty2, class... _Rest>
struct common_type<_Ty1, _Ty2, _Rest...> : _Common_type3<void, _Ty1, _Ty2, _Rest...> {};
Jag känner att jag missar egentliga syftet med common_type och hur den gynnar additionen. Vad är det man gör här med sina templates? Jag ser inga beräkningar eller liknande för att omvandla enheterna. Sen känns det bara mer förvirrande att gräva djupare.