我有一个由 EulerAngle 类继承的 Vector 类。我希望能够在 EulerAngle 对象上使用 Vector 类中的运算符函数,而不必重写 EulerAngle 类中的运算符并尽可能将 Vector3 更改为 Angle。我怎么能这样做?
class Vector3 {
public:
float x, y, z;
// ctors...
__forceinline Vector3() : x{}, y{}, z{} {
__forceinline Vector3( float x, float y, float z ) : x{ x }, y{ y }, z{ z } {
}
// functions...
// operators...
__forceinline Vector3 &operator +=( const Vector3 &other ) {
x += other.x;
y += other.y;
z += other.z;
return *this;
}
__forceinline Vector3 &operator +=( float scalar ) {
x += scalar;
y += scalar;
z += scalar;
return *this;
}
__forceinline Vector3 operator +( float scalar ) const {
return Vector3( x + scalar, y + scalar, z + scalar );
}
__forceinline Vector3 operator +( const Vector3 &other ) const {
return Vector3( x * other.x, y * other.y, z * other.z );
}
}
class EulerAngle : public Vector3 {
private:
};
// example, MSVC says this is an error and that there is no suitable conversion from EulerAngle to Vector3
EulerAngle ang = { 1.f, 1.f, 1.f };
ang += 5.f
在回答了几个问题后,我添加了以下代码来完成这项工作。但是我仍然想知道是否有更好的方法来实现这一点?
class EulerAngle : public Vector3 {
public:
using Vector3::Vector3;
__forceinline EulerAngle( const Vector3 &other ) : Vector3( other ) {
}
};
最佳答案
您可以使用 user-defined conversion从 Vector3
到您想要的类型,当它不是从 Vector3
继承时使用静态断言。
template<typename T>
operator T() const
{
static_assert(std::is_base_of<Vector3, T>::value, "T is not inherited from Vector3");
return T{x,y,z};
}
LIVE DEMO
============================================= ================
插件
随着 C++20
和 concepts 的引入,上面的代码可以改写为:
template<typename T>
requires std::DerivedFrom<T,Vector3>
constexpr operator T() const
{
return T{x,y,z};
}
LIVE DEMO
关于c++ - 允许继承类使用相同的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56031170/