2

I apologize for the total noob question, but I just cannot find an answer. I googled, searched here, searched C++ array documentation, and some C++ array tutorials.
The question is simple. Why does

#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
      short pixelarray[3][3] = {{1,1,1},{0,0,0},{-1,-1,-1}};
      ... //do stuff.  Imagine a loop here, and BIG array - I'm just simplifying it for StackOverflow
      pixelarray = {{1,0,-1},{1,0,-1},{1,0,-1}};

    return 0;
}

result in an error?

1>arraytest.cpp(11): error C2059: syntax error : '{'

How do I put a static array inside my array? I realize I could set each item individually, but there has to be a better way.

john k
  • 6,268
  • 4
  • 55
  • 59

6 Answers6

6

Built-in arrays in C++ have their problems, and not being assignable does make them rather inflexible. I'd stick with std::array, a C++11 container that emulates a better style of array, which allows a somewhat similar syntax to what you're looking for:

std::array<int, 3> arr{{1, 2, 3}};
std::array<int, 3>{{4, 5, 6}}.swap(arr);
//now arr is {4, 5, 6}

Here's a full sample. The trick is to use the initializer list on a newly-constructed array and then swap that with yours. I believe that the next C++ update is going to remove the need for the double braces as well, which makes it an even closer match to familiar syntax.

chris
  • 60,560
  • 13
  • 143
  • 205
3

Initializer lists can be used just for initialization :)
Like when you declare your variable:

short pixelarray[3][3] = {{1,1,1},{0,0,0},{-1,-1,-1}}; // this is ok

You have to remove this:

pixelarray = {{1,0,-1},{1,0,-1},{1,0,-1}};

And assign new values manually (i.e. pixelarray[x][y] = or with a memcpy(pixelarray, <some other array>, sizeof(pixelarray)))

imreal
  • 10,178
  • 2
  • 32
  • 48
  • does not answer the question, either why a 'syntax' error, or how to reset an array. – john k Dec 20 '12 at 01:27
  • 1
    @user396483: You can't "reset" an array. Arrays are not assignable. You can of course merge two arrays, but you'll have to declare a third large enough to hold them both. – Ed S. Dec 20 '12 at 01:32
2

If you don't want to assign each individual element manually, you can do this:

short pixelarray2[3][3] = {{1,0,-1},{1,0,-1},{1,0,-1}};
memcpy(pixelarray, pixelarray2, sizeof(pixelarray));

As @Nick points out: initializer lists are not for assignment.

Anthony
  • 12,177
  • 9
  • 69
  • 105
  • 2
    You don't need to `sizeof (short) * 3 * 3` manually; you can just `sizeof pixelarray`. – melpomene Dec 20 '12 at 01:35
  • @melpomene That's true, although the former is not incorrect. If you wanted to get pedantic, it should probably be `min(sizeof(pixelarray), sizeof(pixelarray2))`, just in case one of them changes in the future and the other doesn't. – Anthony Dec 20 '12 at 01:42
  • 1
    @anthony-arnold, I'd suspect that would be a buggy problem. In that case, all other things aside, I'd put in a `static_assert(sizeof pixelarray == sizeof pixelarray2, "Sizes of pixel arrays must be equal.");` – chris Dec 20 '12 at 01:49
2

Arrays are not assignable, so the short answer is that you can't do exactly what you're asking for. The most direct way to do something similar enough for most purposes is probably a 2D array class that acts as a wrapper around a std::vector, on the order of the one I posted in a previous answer.

If you insist on staying with C-style arrays, one possibility would be to use a pointer:

int main() { 
    typedef short array[3];

    array pixelarray0[3] = {{1,1,1},{0,0,0},{-1,-1,-1}};
    array pixelarray1[3] = {{1,0,-1},{1,0,-1},{1,0,-1}};

    array *pixelarray = pixelarray0;

    // when needed:
    pixelarray = pixelarray1;
}
Community
  • 1
  • 1
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • A link to an older answer that contains a link to an older answer? Must be answerception. – chris Dec 20 '12 at 01:39
  • @chris: I've written a *lot* of answers -- but not quite so many we need Dijkstra's or Kruskal's algorithms to trace through the links. :-) – Jerry Coffin Dec 20 '12 at 01:40
2

Taking this question from a straight C context, you can have different constant arrays and just copy them with memcpy:

typedef short TArray[3][3];
const TArray a1 = {{1,1,1},{0,0,0},{-1,-1,-1}};
const TArray a2 = {{1,0,-1},{1,0,-1},{1,0,-1}};

// ...    
TArray a;
memcpy( a, a2, sizeof(TArray));

Or you could exploit C99 struct copying, but I'd consider this a dangerous hack because the structure might be padded to be larger than the array, or have a different alignment.

typedef struct {
    TArray arr;
} TDummyArray;

// ...
TArray a;
*(TDummyArray*)a = *(TDummyArray*)a2;
paddy
  • 60,864
  • 6
  • 61
  • 103
0

Once you have declared your array there is no way to use the assignment operator to reassign the entire content of the array.

So to change the contents or your array after this:

short pixelarray[3][3] = {{1,1,1},{0,0,0},{-1,-1,-1}};

You need to either loop through the array and manually change each value, or you something like std::memcpy to copy your new values over.

But you should really not be using an array in the first place, use some fromthing the std collections library instead like std::array or std::vector. Only use arrays if you have a really really good reason why you can't use a collection.

David Saxon
  • 1,406
  • 1
  • 12
  • 23