0

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,

bou
  • 147
  • 1
  • 8
  • Why would you take a container that already dynamically allocates elements, and put dynamically allocated elements inside it? What possible purpose could that serve? I think more context on what you're trying to do, not just how you're currently trying to do it, is needed. – underscore_d Jun 09 '20 at 10:13
  • How about not storing `int*` in `std::valarray`? And do you really want to change your pointer address by hand? That's never a good idea. – Darkproduct Jun 09 '20 at 10:20
  • @underscore_d and @Darkproduct :This is just a simplified example. My intention was to take advantage of `std::valarray` to increment many pointers "at the same time". – bou Jun 09 '20 at 10:30
  • Your program has undefined behaviour. `new int(2);` dynamically allocates one `int` with the value `2`, not 2 `int`s – Caleth Jun 09 '20 at 12:30
  • @Caleth OK sorry, I wanted to write `new int[2]` – bou Jun 10 '20 at 14:03
  • I corrected the example accordingly. – bou Jun 10 '20 at 14:13

3 Answers3

1

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).

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • Yes, that's why I am looking for a "type" which would be suitable to increment an `int*`. Is that possible? Moreover, the `int` from operation `+= 1` is converted appropriately in a standard way to increment a pointer. – bou Jun 09 '20 at 10:41
  • @bou you can create your own overload and have it do whatever you want. Besides that, you can't do much of anything. – Aykhan Hagverdili Jun 09 '20 at 11:09
1

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; });
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
Caleth
  • 52,200
  • 2
  • 44
  • 75
0

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.

Faro
  • 3
  • 1
  • Since operator `+=` does work for `int*` I was looking for a way to use this operator. – bou Jun 09 '20 at 10:40