9

Depending on a variable, I need to select the SeedPositions32 or SeedPositions16 array for further use. I thought a pointer would allow this but I can't seed to make it work. How do you declare a pointer to a C++11 std::array? I tried the below.

array<int>* ArrayPointer;
//array<typedef T, size_t Size>* ArrayPointer;
array<int,32> SeedPositions32 = {0,127,95,32,64,96,31,63,16,112,79,48,15,111,80,
                               47,41,72,8,119,23,104,55,87,71,39,24,7,56,88,103,120};
array<int,16> SeedPositions16 = {...}
whitebloodcell
  • 308
  • 1
  • 4
  • 10
  • 1
    You can use std::array::data to get the data pointer. The pointer returned will only be typed with the first template parameter of the std::array. It looks like this is what you want. – Ben Apr 09 '14 at 08:47
  • 8
    This question is a case of [the XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem): You have a solution you want to use, and asks for advice to make that specific solution work. But you never tell us what problem you are *actually trying to solve*. It might be that there are other (maybe even better) solutions. – Some programmer dude Apr 09 '14 at 08:49
  • 1
    @JoachimPileborg - I am trying to create a tennis tournament simulator, where the outcomes of the games are random (sort of). At Grand Slams there are 128 players, 32 of which are seeded. At the moment I am trying to place the seeds in the draw at the appropriate position. I have the randomly generated strengths of the players in an ascending sorted array. Ideally I would have an algorithm to put each player in the proper position in the draw, but I haven't been able to come up with one yet, so I typed the positions as array indexes in manually, intending to then select the appropriate one. – whitebloodcell Apr 09 '14 at 09:14

4 Answers4

19

std::array has a template parameter for size. Two std::array template instantiations with different sizes are different types. So you cannot have a pointer that can point to arrays of different sizes (barring void* trickery, which opens its own can of worms.)

You could use templates for the client code, or use std::vector<int> instead.

For example:

template <std::size_t N>
void do_stuff_with_array(std::array<int, N> the_array)
{
  // do stuff with the_array.
}

do_stuff_with_array(SeedPositions32);
do_stuff_with_array(SeedPositions16);

Note that you can also get a pointer to the data:

int* ArrayPtr =  SeedPositions32.data();

but here, you have lose the size information. You will have to keep track of it independently.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • it is possible to get a pointer to the underlying "bare" array ? – Moha the almighty camel Apr 09 '14 at 08:47
  • @Mhd.Tahawi std::array::data or std::array[0]. – Ben Apr 09 '14 at 08:48
  • 2
    @Mhd.Tahawi You can get a pointer to the underlying data, but you lose the type information (specifically, the size.) – juanchopanza Apr 09 '14 at 08:49
  • 2
    Note: an often used class is `ArrayRef` or `array_view` containing a pointer to the array and the array size, as well as overloading all useful operators (presenting a container interface). It's unfortunately not Standard yet, but easy enough to code. Its main issue is to coordinate its lifetime with that of the underlying storage... – Matthieu M. Apr 09 '14 at 09:20
  • Disappointed there's no ArrayRef/array_view in `std`. Rust also has separate types for different length statically/stack allocated arrays (`[T; N]`), but there at least they all coerce to `&[T]`, with the compile-time length automatically being converted to a runtime length. – zstewart Feb 23 '18 at 04:19
3

You can simply access the content of the std::array as a raw C-like array pointer using the std::array::data() member function:

int* arrayPointer = useSeedPositions32 ? SeedPositions32.data() : SeedPositions16.data();
Mr.C64
  • 41,637
  • 14
  • 86
  • 162
2

In his answer juanchopanza explained very well why what you want cannot work.

The question is why would you want to do that? There is no way where you could use a (pointer to) std::array<int,32> in place of std::array<int,16>.

The point of std::array<> is to keep track of the number of elements at compile time (and also to avoid memory allocation for small fixed-sized arrays). If you instead want the number of elements to be managed at run time, you should presumably not use std::array<>, but std::vector.

The alternative of obtaining a pointer to the underlying data (using std::array::data() as proposed in other answers) and keeping track of the number of elements by yourself is somewhat dangerous and not really recommendable. The problem is that you must ensure that the pointer is never dangling.

Finally, I cannot find any possible use case. In order to use your pointer, you must declare both an array<int,32> and an array<int,16> object, yet use only one of them. Why don't you simply only declare a array<int,32> and use only its first 16 elements if not all 32 are needed?

Walter
  • 44,150
  • 20
  • 113
  • 196
  • The first 16 elements of array are not the same as stored in array. Lacking an algorithm for their placement, I need to choose one set of positions depending on the number of players in the tournament. I'll try again for an algorithm before deciding which of the solutions to use. Thank you for your help. – whitebloodcell Apr 09 '14 at 10:32
1

You could do something like this:

int * myArray = use32 ? &SeedPositions32[0] : &SeedPositions16[0];
microtherion
  • 3,938
  • 1
  • 15
  • 18