c++vectoroperator-overloadingtemplate-classes

c++ Operator overloading for template vector struct


I am creating a template Vector<T,n> struct and trying to overload some arithmetic operations. However, even when I did overload the operators, I'm getting no match errors. Code shown below.

In my Vector.hpp file I have the following code:

template <typename T, int n>
struct Vector
{
    T data[n];

    template <typename S>
    Vector<T, n> operator+(Vector<S, n> &vec);

    ...

}

typedef Vector<int, 3> vec3i;

And in Vector.cpp:

template <typename T, int n>
template <typename S>
Vector<T, n> Vector<T, n>::operator+(Vector<S, n> &vec)
{
    T arr[n];
    for (int i = 0; i < n; i++)
    {
        arr[i] = this->data[i] + (T)vec->data[i];
    }
    Vector<T, n> result(arr);
    return result;
}

However, when I invoked this operator in main, it won't compile:

int main(int argc, char const *argv[])
{
    vec3i vec1 = Vec3i(1,2,3);
    vec3i vec2 = Vec3i(4,5,6);
    vec3i vec3 =  vec1 + vec2;
    std::cout << vec3.x << "," << vec3.y << "," << vec3.z <<"\n";
    return 0;
}

Here's the error message:

no operator "+" matches these operands -- operand types are: vec3i + vec3i
no match for ‘operator+’ (operand types are ‘vec3i {aka Vector<int, 3>}’ and ‘vec3i {aka Vector<int, 3>}’)GCC
no match for ‘operator+’ (operand types are ‘vec3i {aka Vector<int, 3>}’ and ‘vec3i {aka Vector<int, 3>}’)GCC

Any idea on what I'm doing wrong?


Solution

  • Since addition is a binary operator you need to supply two arguments to overload it. Furthermore, if your addition operator should be commutative, it should be implemented as a non-member.

    Here is a working example:

    class X
    {
     public:
      X& operator+=(const X& rhs) // compound assignment (does not need to be a member,
      {                           // but often is, to modify the private members)
        /* addition of rhs to *this takes place here */
        return *this; // return the result by reference
      }
    
      // friends defined inside class body are inline and are hidden from non-ADL lookup
      friend X operator+(X lhs,        // passing lhs by value helps optimize chained a+b+c
                         const X& rhs) // otherwise, both parameters may be const references
      {
        lhs += rhs; // reuse compound assignment
        return lhs; // return the result by value (uses move constructor)
      }
    };
    

    which I shamelessly stole from here.