0

Is it possible to overload addition operator(+) for the addition of arrays? Something like:

double operator+ (double a[], double b[])
{
    double c[];

    c[] = a[] + b[];

    return c;
}
Shibli
  • 5,879
  • 13
  • 62
  • 126
  • 1
    You're dealing with raw arrays. The problem is that you do not know the size of the array. And "a[] + b[];" doesn't work :) – Sceptical Jule May 29 '13 at 22:49

5 Answers5

4

No.

A parameter of type "array of T" is adjusted, at compile time, to type "pointer to T", so your declaration:

double operator+ (double a[], double b[])

really means:

double operator+ (double *a, double *b)

And you can't define an overloaded operator+ for pointer types (at least gcc doesn't think so, and I believe it's correct).

Nor can you declare a function with an array type as its return type; if you try, it's not adjusted to a pointer type, it's just illegal.

You can define functions that take arguments of some container type (std::vector, std::array) -- which is likely to be more useful anyway.

Be sure to think about what your operator+ should do if the left and right operands have different sizes. (Throwing an exception is one reasonable approach.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

You can't overload global operators taking operands of non-class type. Fortunately there is std::vector<T> (which is of class type) that we can use instead:

#include <vector>
#include <algorithm>
#include <iostream>

template <typename T>
std::vector<T> operator +(std::vector<T> lhs, std::vector<T> rhs)
{
    std::vector<T> temp;
    temp.insert(temp.end(), lhs.begin(), lhs.end());
    temp.insert(temp.end(), rhs.begin(), rhs.end());

    return temp;
}

int main()
{
    std::vector<int> x{1, 2, 3}, y{4, 5, 6};

    std::vector<int> z(x + y);

    for (auto a : z)
        std::cout << a << ' '; // 1 2 3 4 5 6
}

Here is a demo.

David G
  • 94,763
  • 41
  • 167
  • 253
  • 1
    I'd make the parameters not need an lvalue. – chris May 29 '13 at 23:18
  • 1
    If you're using C++11 you could also mention `std::array`.. seems like no one likes/remembers it? – dyp May 29 '13 at 23:32
  • @DyP I would've mentioned it but I had trouble implementing it . – David G May 29 '13 at 23:34
  • [Works fine for me](http://coliru.stacked-crooked.com/view?id=b00e236b0010e064b0bf207b40c0ab4c-f674c1a6d04c632b71a62362c0ccfc51) – dyp May 29 '13 at 23:43
  • @DyP You're adding the contents of the arrays. I thought the OP was asking to *concatenate* the arrays... – David G May 29 '13 at 23:45
  • *shrug* [works for me, too](http://coliru.stacked-crooked.com/view?id=115517b0b3c9197a1037fb43fda20d22-f674c1a6d04c632b71a62362c0ccfc51) ;) – dyp May 29 '13 at 23:47
1

No you can't. But you can write a class that wraps arrays this way:

#include <iostream>
#include <algorithm>

class Array {
    int* arr;
    int arr_size;

    public:
        Array(int n): arr(new int[n]), arr_size(n) {}
        ~Array(){ delete[] arr; }
        int& operator[](int n) { return arr[n]; }
        Array operator+(Array& other) {
            Array to_return(arr_size);
            for(int i=0 ; i < std::min(arr_size, other.arr_size) ; i++)
                to_return[i] = arr[i] + other[i];
            return to_return;
        }
};

int main() {
    int tmp1[] = {1, 2, 3, 4};
    int tmp2[] = {5, 6, 7, 8};
    Array arr(4), arr2(4);
    for(int i=0 ; i < 4 ; i++) {
        arr[i] = tmp1[i];
        arr2[i] = tmp2[i];
    }
    for(int i=0 ; i < 4 ; i++)
        std::cout << (arr + arr2)[i] << ' ';

    return 0;
}

Output:

6 8 10 12
aldeb
  • 6,588
  • 5
  • 25
  • 48
  • 3
    And with C++11 you can just use [`std::array`](http://en.cppreference.com/w/cpp/container/array). – dyp May 29 '13 at 23:31
  • Your `operator+` is going to have problems if the right operand is shorter than the left one. And in the destructor, shouldn't `delete arr;` be `delete[] arr;`? – Keith Thompson May 29 '13 at 23:44
  • @Keith: See my edited post. Thanks for the observation! (Note: I know the class may not be complete. That was just for demonstration purpose) – aldeb May 30 '13 at 00:03
  • 1
    I think it really needs a copy-ctor. Otherwise `Array to_return = Array(arr_size);` will result in two arrays (using the implicitly defined copy ctor) with the same pointer `arr`. Both deleting it when destroyed -> UB. See [Rule of Zero](http://flamingdangerzone.com/cxx11/2012/08/15/rule-of-zero.html) – dyp May 30 '13 at 00:08
  • The line `Array to_return = Array(arr_size);` creates a temporary and copies it into `to_return` (though the compiler may elide that copy). If it does not elide the copy, you'll have UB because in that case you have to instances of `Array` using (and deleting) the same pointer. You could change the line to `Array to_return(arr_size);`, but the Rule-of-Three problem remains (when you change the line, your program would not contain UB any more). – dyp May 30 '13 at 00:25
  • @DyP: See my edited post. Sorry I misunderstood your comment. Thanks! So how do you explain I didn't get any errors on valgrind? (I compiled with `g++ -Wall`). About the rule of three: I did know about it already but I don't think it's really useful here since the purpose of the code I proposed is not to be complete but just to give an idea of "how to do it" to the OP. What do you think? – aldeb May 30 '13 at 00:30
  • Copy elision :) (looks like g++ even omits this copy w/o optimization switches) – dyp May 30 '13 at 00:31
  • @DyP: If you want to add the cpy constructor anyway, feel free to edit my post :) – aldeb May 30 '13 at 00:41
1

Not directly. In principle you can write functions that take (references to) arrays:

// returns a[0]*b[0] + a[1]*b[1] + ... + a[N-1]*b[N-1]
template <int N>
double innerProduct(double const (& a)[N], double const (& b)[N])
{
    double sum = 0;
    for (size_t i = 0; i < N; ++i) sum += a[i] * b[i];
    return sum;
}

But there are several problems:

So either wrap your arrays in a user defined type, or use a regular function (like addInto). For the return value, either pass a result array to be filled as a parameter, or return some other type like std::vector.

Example:

// c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; ... c[N-1]=a[N-1]+b[N-1];
template <int N>
void addInto(double const (& a)[N], double const (& b)[N], double (& out)[N])
{
    for (size_t i = 0; i < N; ++i) out[i] = a[i] + b[i];
}
Community
  • 1
  • 1
Anders Johansson
  • 3,926
  • 19
  • 19
0

It is possible to overload any operator for a class that you write. Keep in mind that operator overloading is only to make code more readable, if your operators do things that aren't very obvious you probably should overload it at all. Also to this specific one you are thinking of you would probably have to write your own wrapper class for arrays. You cannot overload it directly because operator + is already defined for pointers. You may be able to overload operator + for the vector or array datatypes in c++

aaronman
  • 18,343
  • 7
  • 63
  • 78