I'm a mechanical engineer trying to create a simulation library with physical types (distance, force, moments, acceleration, velocity etc.) along with some vector maths (template Vector3D) to support those types. Everything is going smoothly for normal vector operations except for the cross product for which I want to apply an overload to the operator '^'. A cross product operation takes in two different types and returns a third see below for a list of examples.
Vector3D<Moment> = Vector3D<Distance> ^ Vector3D<Force>;
Vector3D<Acceleration> = Vector3D<AngularAcceleration> ^ Vector3D<Velocity>;
Vector3D<Velocity> = Vector3D<AngularVelocity> ^ Vector3D<Distance> etc. etc.
Now ideally I would love to not setup a different method for the '^' operand overload based on the return type and input arguments. Now I know the code below does not work fault of you cannot do a classical operator overload with three different templates and the compiler will not know what to do.
template <typename T, typename U, typename V>
Vector3D<T> operator^ (const Vector3D<U>& p_left, const Vector3D<V>& p_right)
And sure enough I get the following compilation error C2593: 'operator ^' is ambiguous. I was wondering if there was some type inference and/or instantiation that could be put to good use here though I've done some reading online nothing seems to fit the specific requirements at hand. I figured that I would need constructors for the conversion of types but that by itself will not be enough
/// Constructor
/// \param p_value Moment arm
/// \param p_unit Force
//
Moment(Distance p_radius, Force p_force);
/// Constructor
/// \param p_omega Magnitude of angular velocity
/// \param p_velocity Magnitude of linear velocity
//
Acceleration(AngularVelocity p_omega, Velocity p_velocity);
/// Constructor
/// \param p_value Angular velocity
/// \param p_unit Radius
Velocity(AngularVelocity p_omega, Distance p_radius);
Your assistance in this matter would be of great help for me as programming is still an area where I'm constantly learning... Please see below for some further information on my class Vector3D<>. Thank you in advance!
//Vector3D.h
template <typename T>
class Vector3D
{
public:
//////////////////////////////////////////////////////////////////////////
// *** CONSTRUCTORS ***
//////////////////////////////////////////////////////////////////////////
/// Default Constructor
//
Vector3D(void);
/// External initialization Constructor
//
Vector3D(const T& p_x, const T& p_y, const T& p_z);
//////////////////////////////////////////////////////////////////////////
// *** DESTRUCTOR ***
//////////////////////////////////////////////////////////////////////////
/// Destructor
//
~Vector3D(void);
template <typename U, typename V>
friend Vector3D<T> operator^ (const Vector3D<U>& lhs, const Vector3D<V>& rhs);
'''
private:
//////////////////////////////////////////////////////////////////////////
// *** PRIVATE DATA MEMBERS ***
//////////////////////////////////////////////////////////////////////////
T m_elem[3];
}
//Vector3D.cpp
/// Calculate the cross product
//
template <typename T, typename U, typename V>
Vector3D<T> operator^ (const Vector3D<U>& p_left, const Vector3D<V>& p_right)
{
Vector3D<T>cross_product;
// Calculation
cross_product.m_elem[0] = T(p_left.m_elem[1], p_right.m_elem[2]) - T(p_left.m_elem[2], p_right.m_elem[1]);
cross_product.m_elem[1] = T(p_left.m_elem[2], p_right.m_elem[0]) - T(p_left.m_elem[0], p_right.m_elem[2]);
cross_product.m_elem[2] = T(p_left.m_elem[0], p_right.m_elem[1]) - T(p_left.m_elem[1], p_right.m_elem[0]);
return cross_product;
}
template class Vector3D<double>;
template class Vector3D<double>;
template class Vector3D<Numeric>;
template class Vector3D<Force>;
template class Vector3D<Acceleration>;
template class Vector3D<Velocity>;
template class Vector3D<Distance>;
template class Vector3D<Moment>;
template class Vector3D<AngularAcceleration>;
template class Vector3D<AngularVelocity>;
template class Vector3D<Angle>;