0

Following my question about passing array as const argument, I am trying to figure out how to write a method where the argument is a const array of fixed size const array. The only writable thing would be the content of these arrays.

I am thinking about something like this:

template <size_t N>
void myMethod(int* const (&inTab)[N])
{
    inTab = 0;       // this won't compile
    inTab[0] = 0;    // this won't compile
    inTab[0][0] = 0; // this will compile
}

The only problem in this solution is that we don't know the first dimension. Does anyone have a solution for this?

Thanks in advance,

Kevin

[Edit]

I don't want to use std::vector or such dynamically allocated arrays.

Community
  • 1
  • 1
Kevin MOLCARD
  • 2,168
  • 3
  • 22
  • 35
  • `The only writable thing would be the content of these arrays.` and `the argument is a const array ` do not go well together – SingerOfTheFall Jul 24 '12 at 09:30
  • I'm not sure I understand, but passing an array of arrays is done like this: `template void myMethod(int (&inTab)[N][M])`. – R. Martinho Fernandes Jul 24 '12 at 09:33
  • @SingerOfTheFall: It makes perfect sense: it's a constant array of pointers to writable arrays. – Mike Seymour Jul 24 '12 at 09:37
  • However, you still have to pass an continuous block of data to this method, right? – Spook Jul 24 '12 at 09:45
  • @MikeSeymour, hmm, I thought `where the argument is a const array of fixed size const array` means " a const array of const arrays"... – SingerOfTheFall Jul 24 '12 at 09:45
  • @SingerOfTheFall: Oh yes, I didn't notice the second "const". Presumably that's a typo, since the code clearly uses pointers to writable arrays. – Mike Seymour Jul 24 '12 at 09:48
  • @Spook: that's the point, I don't want to be oblige to pass a continuous block of data to this method. – Kevin MOLCARD Jul 24 '12 at 09:54
  • @MikeSeymour & SingerOfTheFall: sorry if I was not clear. I want `inTab` and all `inTab[]` as const but all `inTab[][]` writable. Is it more understandable now? – Kevin MOLCARD Jul 24 '12 at 09:57
  • @KevinMOLCARD: See my answer below. Presuming you only really want to achieve line 2 and 3 in your code, how about just removing that `const`? – Keldon Alleyne Jul 24 '12 at 09:59
  • @KevinMOLCARD What I meant is, that you can only pass statically allocated arrays with their sizes known at compile time, which are, actually, continuous blocks of memory :) – Spook Jul 24 '12 at 10:01
  • @avasopht: I think I did explain well what I needed. My code is exactly what I need except that it keeps the first dimension unknown. – Kevin MOLCARD Jul 24 '12 at 10:02
  • @Spook: so this means that I can not do better than I wrote? – Kevin MOLCARD Jul 24 '12 at 10:05
  • @KevinMOLCARD: So what you're saying is that you want to repoint `inTab`? And no, you never explicitly stated the need to repoint `inTab`, you actually said that you only wanted to write to the array's contents (not making mention of the array pointers) Which is contrary to line 1 and 2. And by line 1 and 2, I mean the `inTab=0;` and `inTab[0] = 0;`. Perhaps my error was referencing the lines inside the functions, which would have really been lines 4 and 5, sorry. – Keldon Alleyne Jul 24 '12 at 10:07
  • @KevinMOLCARD That mostly depends on your needs. Take into consideration, that static arrays are placed on stack rather than on heap (stack's size is tightly restricted), they cannot be resized, and the compiler will create another function for each set of dimensions you will use in your code. I think, that using standard containers like std::vector or std::array might prove more flexible and easy to further expand. But I'm quite a fan of OOp and I don't like C-style programming, so take my comments with a grain of salt :) – Spook Jul 24 '12 at 10:38
  • @avasopht: We are still misunderstanding ourselves. I want a compiler error when writing `inTab = 0` and `inTab[0] = 0`. – Kevin MOLCARD Jul 24 '12 at 12:02
  • Oh lol, yes that's fine then ^_^ – Keldon Alleyne Jul 24 '12 at 12:42

2 Answers2

5

If both dimensions are known at compile time, then you could use a 2-dimensional array (in other words, an array of arrays) rather than an array of pointers to arrays:

template <size_t N, size_t M>
void myMethod(int (&inTab)[N][M])
{
    inTab = 0;       // this won't compile
    inTab[0] = 0;    // this won't compile
    inTab[0][0] = 0; // this will compile
}

int stuff[3][42];
myMethod(stuff); // infers N=3, M=42

If either dimension is not known at runtime, then the arrays presumably need to be dynamically allocated. In that case, consider using std::vector both to manage the allocated memory and to keep track of the size.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

The reference prevents line 4 (inTab = 0;), because you've made inTab a reference. The const prevents line 5 (inTab[0] = 0;) because an inTab pointer is const.

Keldon Alleyne
  • 2,103
  • 16
  • 23