I have a Vector class that is template based. I have a unit conversion template that is based on Scott Meyers Dimensional Analysis in C . I'm not going to list it as it is complex, unless the problem can't be solved without those details. I'm using the casting operator for when I need to pass the data to outside functions.
template<typename T>
struct XYZVector
{
operator Point3D() { return Point3D(x, y, z); }
}
If I use T as a double it works fine. But when I do this I need a specialization.
Point3D vecOut = XYZVector<Unit::usFoot>(x,y,z);
Will fail because when converting a Unit object you need to use an as() method.
operator Point3D() { return Point3D( x.as<T>(), y.as<T>(), z.as<T>() ); }
So I need someway to say if T is a Unit use this line, other wise use the next line.
template<typename T>
struct XYZVector
{
//if typename T is a Unit type use this
operator Point3D() { return Point3D( x.as<T>(), y.as<T>(), z.as<T>() ) }
//otherwise use this
operator Point3D() { return Point3D(x, y, z); }
}
Is this possible?
CodePudding user response:
if constexpr
to the rescue.
operator Point3D() {
if constexpr (std::is_same_v<std::remove_cvref_t<T>,Unit>){
return Point3D(x.as<T>(),y.as<T>(),z.as<T>());
}else{
return Point3D(x,y,z);
}
}
CodePudding user response:
I would use overloads as customization point:
// overload for built-in type (no ADL)
double to_double(double d) { return d;}
template <typename T>
struct XYZVector
{
// ...
operator Point3D() const {
return Point3D(to_double(x),
to_double(y),
to_double(z));
}
};
// The ones which can be found by ADL can be placed after
namespace Unit {
double to_double(usFoot u) { return u.as<double>(); }
}