Search code examples
c++operator-overloadingoperatorsoperator-keywordreturn-type

c++ binary arithmetic operator for returning derived type?


im wraping glm library and when i encapsulate the Vector3 derived from glm::vec3, i found i can literally use Vector3 a = b + c where b and c are both Vector3 but when i tryed it on my own project, i got no suitable user-defined conversion error, here's my code:

#include <iostream>
#include <assert.h>
using namespace std;

template <typename T>
struct CBase
{
    CBase(T _v) : value(_v) { }
    T value = 0;
};

template <typename T>
CBase<T> operator +(const CBase<T>& value1, const CBase<T>& value2);

template <typename T>
inline CBase<T> operator +(const CBase<T>& value1, const CBase<T>& value2)
{
    return CBase<T>(value1.value + value2.value);
}

typedef CBase<int> cbas;

struct C : cbas
{
    using cbas::cbas;
};


int main()
{
    C c = C(100);
    C c1 = C(101);
    cbas numC = c + c1; //can only return for base type
    //C numC = c + c1; //error line
    cout << numC.value << endl;
}

while glm code

//type_vec3.hpp
    template <typename T, precision P = defaultp>
    struct tvec3
    {
            union
            {
                struct{ T x, y, z; };
                struct{ T r, g, b; };
                struct{ T s, t, p; };
            }
            //...
    }
//type_vec.hpp
    typedef tvec3<float, highp>     highp_vec3;
    typedef highp_vec3          vec3;
//tyoe_vec3.inl
    template <typename T, precision P>
    GLM_FUNC_QUALIFIER tvec3<T, P> operator+(tvec3<T, P> const & v1, tvec3<T, P> const & v2)
    {
        return tvec3<T, P>(
            v1.x + v2.x,
            v1.y + v2.y,
            v1.z + v2.z);
    }
//my Definition.h
    #define VL_AL_VECTOR(N) glm::vec##N
    #define VL_AL_VECTOR_CTOR(N) vec##N
    struct Vector3 : VL_AL_VECTOR(3)
    {
        using VL_AL_VECTOR(3)::VL_AL_VECTOR_CTOR(3);
        const static Vector3 one;
        const static Vector3 zero;
        const static Vector3 left;
        const static Vector3 right;
        const static Vector3 up;
        const static Vector3 down;
        const static Vector3 forward;
        const static Vector3 back;
    };

i wonder why Vector3 type can use operator+ for a retrun variable which's type is Vector3 itself while C cannot, appreciate any help.


Solution

  • You could provide a constructor that converts a cbas to C such as:

    struct C : cbas
    {
    
        C (const cbas& c):cbas{c.value}{}
    };