Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializer list for dynamic arrays?

It is possible to give an initializer list to the definition of a static array. Example:

int main()
{
  int int_static[2] = {1,2};
}

Is a similar initializer list possible for a dynamic array?

int main()
{
  int* int_ptr = new int[2];
}

This is closer to what I am trying to do:

struct foo
{
  foo(){}
  foo(void * ptr): ptr_(ptr) {}
  void * ptr_;
};

int main()
{
  foo* foo_ptr = new foo[10];
}

At initialization time not the default constructor should be called, but foo:foo(void*).

The point of having a static initializer list for a dynamic array might come handy in the case of Just-In-Time compilation for accelerator cores which do have only a limited amount of stack available, but at the same time you construct your objects with a (accelerator compile time = host run time) static initializer list.

I assume not (since this would require the compiler to generate additional code, namely to copy the values of the arguments to the heap location). I think c++0x supports some of this, but I cannot use it. Right now I could use such a construct. Maybe someone knows a trick..

Best!

like image 738
ritter Avatar asked Aug 19 '11 16:08

ritter


2 Answers

At the time the OP posted this question, C++11 support may not have been very prevalent yet, which is why the accepted answer says this is not possible. However, initializing a dynamic array with an explicit initializer list should now be supported in all major C++ compilers.

The syntax new int[3] {1, 2, 3} was standardized in C++11. Quoting the new expression page on cppreference.com:

The object created by a new-expression is initialized according to the following rules:
...
If type is an array type, an array of objects is initialized:
...
If initializer is a brace-enclosed list of arguments, the array is aggregate-initialized. (since C++11)

So, given the OP's example, the following is perfectly legal when using C++11 or newer:

foo * foo_array = new foo[2] { nullptr, nullptr };

Note that by providing pointers in the initializer list, we're actually coaxing the compiler to apply the foo(void * ptr) constructor (rather than the default constructor), which was the desired behavior.

like image 56
DaoWen Avatar answered Sep 20 '22 20:09

DaoWen


No, you cannot do that.

I think C++ doesn't allow this because allowing such thing doesn't add any nice-to-have feature to the language. In other words, what would be the point of dynamic array if you use a static initializer to initialize it?

The point of dynamic array is to create an array of size N which is known at runtime, depending on the actual need. That is, the code

int *p = new int[2]; 

makes less sense to me than the following:

int *p = new int[N]; //N is known at runtime

If that is so, then how can you provide the number of elements in the static initializer because N isn't known until runtime?

Lets assume that you're allowed to write this:

int *p = new int[2] {10,20}; //pretend this!

But what big advantage are you getting by writing this? Nothing. Its almost same as:

int a[] = {10,20};

The real advantage would be when you're allowed to write that for arrays of N elements. But then the problem is this:

 int *p = new int[N] {10,20, ... /*Oops, no idea how far we can go? N is not known!*/ };
like image 30
Nawaz Avatar answered Sep 20 '22 20:09

Nawaz