Operator += applied to std::valarray<int*>

137 Views Asked by At

Here is the example:

    #include <iostream>
    #include <string>
    #include <valarray>

    int main()
    {
      std::valarray<std::string> vs(2);
      // vs[0] += "hello"; // works
      // vs[1] += "hello"; // works
      vs += "hello"; // works
      std::cout << vs[0] << std::endl;
      std::cout << vs[1] << std::endl;

      std::valarray<int*> vi(2);
      vi[0] = new int[2];
      vi[0][0] = 0;
      vi[0][1] = 1;
      vi[1] = new int[2];
      vi[1][0] = 2;
      vi[1][1] = 3;
      std::cout << vi[0][0] << std::endl;
      std::cout << vi[1][0] << std::endl;
      // vi[0] += 1; // works
      // vi[1] += 1; // works
      vi += 1; // error: invalid operands of types 'int*' and 'int*' to binary 'operator+'
      std::cout << vi[0][0] << std::endl;
      std::cout << vi[1][0] << std::endl;
    }

I don't understand this error, if someone may explain this to me.

Is there a workaround?

Best regards,

3

There are 3 best solutions below

1
Caleth On BEST ANSWER

std::valarray doesn't have overloads for heterogeneous binary operations, but it does have a catch-all for other functions, apply.

vi.apply([](int * p){ return p + 1; });
1
Faro On

My last dabble in C++ has been a while, so please excuse any slipups in terms of terminology/details.

What your error boils down to is that += on a valarray attempts to perform the operation on each element of the valarray. And by default (if my memory doesn't deceive me), there's no + operation for integer pointers, which are stored in your valarray. You'd need to specify an overridden + operator for int pointers first.

Also, for an explanation of why the other operations work and vi += 1 doesn't:

 vi[0] += 1; // works
 vi[1] += 1; // works

These work, because (and I don't know if that's what you intended to do) you've placed integers in these vararray fields (new int(n) will create an int with a value of n), each with a value of 2. So vi[0] is 2, as is vi[0]. You could as well have written

vi[0] = 2;
vi[1] = 2;

I'm assuming you were trying to instead have an integer array stored in vi[0]/vi[1], which would've been

vi[0] = new int[2];
vi[1] = new int[2];

The problem is that per documentation, vi[0][0] = 0, etc... simply prompt the valarray to create these fields if they don't exist already, so of course

std::cout << vi[0][0] << std::endl;
std::cout << vi[1][0] << std::endl;

will work.

2
Aykhan Hagverdili On

You can see operator+ overloads for valarray here. As you can see no overload is suitable for what you're trying to do (add an int and a pointer).