We want to use boost::units for strong types but also resort to dimensionless types for compatibility e.g. with other libraries. Is there any way to implement this in a generic fashion ? Something along the lines of the following code (which obviously does not compile)
#include <boost/units/systems/si.hpp>
using namespace boost::units;
using SiTime = quantity<boost::units::si::time, double>;
using SiLength = quantity<boost::units::si::length, double>;
template<typename TIME,typename LENGTH>
struct Kernel{
using time_t = TIME;
using length_t = LENGTH;
};
using KernelD = Kernel<double,double>;
using KernelSi = Kernel<SiTime,SiLength>;
template<typename TO_KERNEL>
struct composite_cast{
template<template <typename> class COMPOSITE,typename FROM_KERNEL>
COMPOSITE<TO_KERNEL> operator()(COMPOSITE<FROM_KERNEL> value){
(void)value;
//how could this work ?
return COMPOSITE<TO_KERNEL>();
}
};
template<typename KERNEL>
struct Foo{
typename KERNEL::length_t length;
typename KERNEL::time_t time;
};
using FooSi = Foo<KernelSi>;
using FooD = Foo<KernelD>;
template<typename KERNEL>
struct Bar{
Foo<KERNEL> a;
Foo<KERNEL> b;
};
using BarSi = Bar<KernelSi>;
using BarD = Bar<KernelD>;
int main(int, char**) {
FooSi fooSi;
FooD fooD = composite_cast<KernelD>(fooSi);
BarSi barSi;
BarD barD = composite_cast<KernelD>(barSi);
return 0;
}
Besides the litany of syntax errors in your sample code, this code won't work because
COMPOSITEneeds to be a template-template argument type:That said, I'd go for explicit conversions here:
Live On Coliru
Explicit Conversion Functions
If you don't want to have the member operators, make them free:
Live On Coliru
Have Your Cake And Eat It Too
Incidentally, the free-function approach ties in really well with your original
composite_castfunction object: