1

I have a grid that I want to pass to another function in which I display it. However, I can't seem to figure out how I would declare that function, to which a multidimensional array is passed by reference.

void foo(bool[][]&); //INCORRECT: how is a correct way to declare this function?

// rest of code :

int main(){
    bool grid[50][50] = {false};
    foo(grid);
    return 0;
}

void foo(bool& grid[][]){
    // do things
}

This should be an elementary question but I'm having a lot of trouble finding a solution.

Chronicle
  • 1,565
  • 3
  • 22
  • 28
  • See the [spiral rule](http://c-faq.com/decl/spiral.anderson.html "Greatest rule ever") to get started. Note that both dimensions must be known because the type of an array changes when the size changes and a reference includes what it refers to as part of the type. – chris Jan 15 '14 at 18:48
  • @chris: That 'spiral rule' is rubbish, surely? As I understand it, it parses `int *p[3][4]` as "array[3] of pointers to array[4] of int", instead of the correct "array[3][4] of pointers to int". – TonyK Jan 15 '14 at 19:57
  • @TonyK, There are a couple slight ambiguities, but multidimensional arrays are treated as one entity. Choosing between these comes with a bit of C++ exposure. The rule's worked extremely well for me 100% of the time. – chris Jan 15 '14 at 20:03
  • There is no room for "a couple slight ambiguities" when you are parsing a C program! I repeat: This spiral rule is rubbish. – TonyK Jan 15 '14 at 20:32

2 Answers2

6

A reference to a 2D array type looks as follows:

T (&)[N][M]

So you want:

void foo(bool(&)[50][50]);

Note that the dimensions must be specified. For the function definition, it will look like:

void foo(bool (&grid)[50][50]) {

If you need to be able to use the function for 2D arrays of various sizes, you can make it a template over the dimensions:

template <std::size_t N, std::size_t M>
void foo(bool(&)[N][M]);

The template will be instantiated for each size of array you pass to it.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 1
    would be helpful to see the use of template args so you don't need to hard-code the dimension sizes – tenfour Jan 15 '14 at 18:51
  • 1
    This template construct works, but depending on the size of that function this could be highly inefficient, because you end up with another copy of that function for each pair (N,M). – pentadecagon Jan 15 '14 at 18:57
  • @pentadecagon: if you need it, you need it. For every instantiation of the function, there's a function with a hard-coded array size that needs it. – tenfour Jan 15 '14 at 19:00
1

You can use one of the followings:

void foo(bool(&grid)[][50]);
void foo(bool(&grid)[50][50]);

But since you have the extreme luck of using C++, you can avoid the C gibberish by using std::array instead:

void foo(std::array<std::array<bool, 50>, 50>&);

Yes, it's longer but it's much more descriptive and easy to remember. And if you are worried about "performance":

The struct combines the performance and accessibility of a C-style array with the benefits of a standard container, such as knowing its own size, supporting assignment, random access iterators, etc.

And guess what? You can even create a templatized alias for it:

template<class T, std::size_t M, std::size_t N = M> using biarray = std::array<std::array<T, M>, M>;

that you can use in your function as:

void foo(biarray<bool, 50>&);
Shoe
  • 74,840
  • 36
  • 166
  • 272
  • Ah, that first one is interesting. I'm guessing it's a reference to a pointer to an array then? – chris Jan 15 '14 at 18:59
  • Well, ok, not exactly from what I'm seeing (because why would the `[]` decay when it's not top level). I guess I just wasn't aware you could have a reference to a `Type[]`. Is there any particular point in doing that? – chris Jan 15 '14 at 19:09
  • @chris, because C. This is probably the best answer I can give you, unfortunately. – Shoe Jan 15 '14 at 19:17