0

Is it possible to get a sparse (non-contiguous) subset of references to array elements?

Suppose I have array a = [1,4,5] and indices pos = [0,1]. I would like to get b = [1,5] without copying elements from a. In other words, I would like to slice into a and create a view called b.

The following errors since "expression is not assignable":

#include <array>

int main() {
  std::array<double,3> a = {1, 4, 5};
  std::array<double, 2> b;
  int c = 0;
  int pos[2] = {0,2};
  for (auto i = a.begin(); i != a.end(); i++) {
    &b[c] = i;
    i++;
  }
  return 0;
}
Oleg
  • 10,406
  • 3
  • 29
  • 57

2 Answers2

1

You can't have direct references in a container. However, if you have access to C++11 you can use std::reference_wrapper:

#include <iostream>
#include <functional>
#include <vector>
#include <array>

int main() {
  std::array<double,3> a = {1, 4, 5};
  std::vector<std::reference_wrapper<double>> b;
  int pos[2] = {0,2};
  for (unsigned int i = 0; i < sizeof(pos) / sizeof(pos[0]); ++i) 
  {
      b.emplace_back(a[pos[i]]);
  }

  for(const auto& viewer: b)
  {
      std::cout << viewer << "\n";
  }
}

Otherwise, just use double*.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • Do you think this will be more efficient than a copy of the elements if the sparsity rate is at only 50%? – Oleg Nov 07 '16 at 09:53
  • 1
    @Oleg Since `emplace_back` does the construction in-place and doesn't copy over a `reference_wrapper` this will generally be really fast. However if your data type is just a `double` I have no doubt that copying over a couple of elements will be fast as well. Which one is faster than the other? Only a benchmark can help you with that. – Hatted Rooster Nov 07 '16 at 09:57
  • I measured execution time of this method against copying the values into a new vector. The `a` array has 1e5 elements, the sparsity is 50%, and the operation is looped 100 times. The copy is more than twice faster. Premature optimization bytes my a** once again... – Oleg Nov 07 '16 at 22:52
0

C++ Standard 8.3.2/4:

There shall be no references to references, no arrays of references, and no pointers to references.

Answered here

However you can have a container array of a class with a referance member (initlized on constractor) and implement a =operator, if it's worth the effort

Community
  • 1
  • 1
O_Z
  • 1,515
  • 9
  • 11