user11467054
user11467054

Reputation:

Allowing inherting class to use the same function

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

Answers (2)

serkan.tuerker
serkan.tuerker

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};
}

LIVE DEMO

===============================================================

ADDON

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};
}

LIVE DEMO

Upvotes: 2

Oliort UA
Oliort UA

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

Related Questions