【发布时间】:2021-03-05 03:31:09
【问题描述】:
我是一名机械工程师,试图创建一个模拟库,其中包含物理类型(距离、力、力矩、加速度、速度等)以及一些矢量数学(模板 Vector3D)以支持这些类型。除了我想对运算符'^'应用重载的叉积之外,正常向量运算的一切都很顺利。叉积运算接受两种不同的类型并返回第三种类型,请参阅下面的示例列表。
Vector3D<Moment> = Vector3D<Distance> ^ Vector3D<Force>;
Vector3D<Acceleration> = Vector3D<AngularAcceleration> ^ Vector3D<Velocity>;
Vector3D<Velocity> = Vector3D<AngularVelocity> ^ Vector3D<Distance> etc. etc.
现在理想情况下,我不想根据返回类型和输入参数为“^”操作数重载设置不同的方法。现在我知道下面的代码不起作用,因为您不能使用三个不同的模板进行经典运算符重载,编译器将不知道该怎么做。
template <typename T, typename U, typename V>
Vector3D<T> operator^ (const Vector3D<U>& p_left, const Vector3D<V>& p_right)
果然我得到了以下编译错误 C2593: 'operator ^' is ambiguous。我想知道是否有一些类型推断和/或实例化可以在这里很好地使用,尽管我已经在网上做了一些阅读,但似乎没有什么符合手头的具体要求。我认为我需要构造函数来转换类型,但这本身是不够的
/// 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);
您在这件事上的帮助将对我有很大帮助,因为编程仍然是我不断学习的领域...请参阅下面有关我的类 Vector3D 的更多信息。提前谢谢!
//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>;
【问题讨论】:
-
您的单位是否已经有
operator*过载?如果Distance * Force已经返回了Moment,我认为应该有办法从decltype中取出U和V的正确返回值。 -
//Vector3D.cpp:模板必须是implemented in headers entirely(少数特殊例外)。 -
@Aconcagua 看起来
Vector3D.cpp正在从该问题的第一个答案中实现“显式实例化您需要的所有模板实例”方法。 -
@NathanPierson 部分。不过,
operator^没有明确的实例化。 -
也许首先让有维度的标量数学工作。有一些图书馆可以做到这一点,例如boost.units。在这种情况下,像
Moment(Distance p_radius, Force p_force)这样的构造函数并不是非常有用。顺便说一句,它被称为“动量”。
标签: c++ templates operator-overloading type-inference