Reputation:
I have a Vector class which is inherited by an EulerAngle class. I want to be able to use the operator function from the Vector class on a EulerAngle object without having to rewrite the operator in the EulerAngle class and changing Vector3 to Angle if possible. How could I do this?
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
After a few answers I added the following code to make this work. However I still want to know if there is a better way to accomplish this?
class EulerAngle : public Vector3 {
public:
using Vector3::Vector3;
__forceinline EulerAngle( const Vector3 &other ) : Vector3( other ) {
}
};
Upvotes: 0
Views: 95
Reputation: 1821
You could make use of user-defined conversion from Vector3
to the type you want with static assertion when it is not inherited from 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};
}
===============================================================
With C++20
and the introduction of concepts, the above code can be rewritten to:
template<typename T>
requires std::DerivedFrom<T,Vector3>
constexpr operator T() const
{
return T{x,y,z};
}
Upvotes: 2
Reputation: 1647
Add implicit constructor from Vector3
and using
for Vector3
constructor in EulerAngle
class
class EulerAngle : public Vector3 {
using Vector3::Vector3;
EulerAngle(const Vector3& from) : Vector3(from) {}
}
if you want to do it like this
EulerAngle ang = { 1.f, 1.f, 1.f };
ang += 5.f;
EulerAngle ang2 = ang + 5.f;
EulerAngle ang3 = Vector3{ 2.f, 2.f, 2.f } + ang2;
Upvotes: 0