So,
I have the following template that multiplies two unit, e.g. velocity and time.
//! The product of the TWO units
template<template<typename> typename QuantityLhs, template<typename> typename QuantityRhs>
struct Multiply
{
template<typename T>
using type = units::unit<typename product_t<QuantityLhs<UNIT_LIB_DEFAULT_TYPE>, QuantityRhs<UNIT_LIB_DEFAULT_TYPE>>::conversion_factor, T>;
};
This is called for example in the following way:
using AccuType = Multiply<Velocity, Time>::type<float>;
The above definition only accepts two template arguments, but I want an arbitrary number of them.
So what I wish to be able to write is something like
using AccuType = Multiply<Velocity, Time, Temperature, Density>::type<float>;
So my idea is to create a variadic template
//! The product of the ANY number of units
template<typename... Quantities>
struct MultiplyMany
{
// Code
};
Unfortunately, I don't know how to make it work. I have this idea that MultiplyMany
would just somehow use a for loop or something to call the basic Multiply
struct as many times as neccesary (iterating over template arguments).
Is that even possible?
The old school method is to create both variadic and regular templates as specializations of the main template, and let the former call the later and itself recursively. Make sure there is no ambiguity between the two!
template<template<typename> typename... Quantities>
struct Multiply;
// The product of one unit is just that unit: one argument
template<template<typename> typename Quantity>
struct Multiply<Quantity>
{
template<typename T>
using type = Quantity<T>;
};
// The product of two OR MORE units: two or more arguments
template<template<typename> typename QuantityLhs, template<typename> typename QuantityRhs, template<typename> typename ... Rest>
struct Multiply<QuantityLhs, QuantityRhs, Rest...>
{
template <typename T>
using type0 = typename Multiply<QuantityRhs, Rest...>::type<T>;
template<typename T>
using type = units::unit<typename product_t<QuantityLhs<UNIT_LIB_DEFAULT_TYPE>, type0<UNIT_LIB_DEFAULT_TYPE>>::conversion_factor, T>;
};
(Not tested due to lack of a minimal reproducible example)
(Actually a multiplication of zero arguments should be allowed, and result in an undimensioned quantity of 1, but I don't know how you handle those).