Initializer List for Dynamic Arrays

Initializer list for dynamic arrays?

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!*/ };

Initialize a dynamic C array within a C++ initializer list

I don't understand how the C array is being initialized within the initializer list.

here:

myArray(int size) : size(size), elements(new int[size])

elements are basicly assigned value returned by new int[size]

You could rewrite it as :

myArray(int size)
{
this->size = size;
elements = new int[size];
std::cout << "Constructed array of size " << size << std::endl;
}

[edit]

This:

// elements(new int[size]); // why will line only work in initializer list?

will not work in the function body, because in this place compiler thinks that you want to call a function named elements, but there is no such function.

The fact that it works in the initializer list is because that is how the language syntax was made.

Declaring array size for dynamically allocated array with initializer list

This is P1009R2: Array size deduction in new-expressions, which was implemented for C++20.

Bjarne Stroustrup pointed out the following inconsistency in the C++ language:

double a[]{1,2,3}; // this declaration is OK, ...
double* p = new double[]{1,2,3}; // ...but this one is ill-formed!

Jens Maurer provided the explanation why it doesn’t work: For a new-expression, the expression
inside the square brackets is currently mandatory according to the C++ grammar. When uniform
initialization was introduced for C++11, the rule about deducing the size of the array from the
number of initializers was never extended to the new-expression case. Presumably this was simply
overlooked. There is no fundamental reason why we cannot make this work [...]

Proposed wording

The reported issue is intended as a defect report with the proposed resolution as follows. The effect
of the wording changes should be applied in implementations of all previous versions of C++ where
they apply.
[...]

From GCC's C++ Standards Support pages we may note that GCC lists P1009R2 as implemented as of GCC 11, and we may verify that GCC 11 have back-ported the implemented to accept the OP's example as well-formed as far back as C++11.

DEMO (GCC 11 / -std=c++11).

How to initialize dynamic array in constructor using initializer_ist?

initializer_list has size method, it gives you information how many elements must be allocated by new, so it could be:

vec(initializer_list<double> ilist)
{
elements = ilist.size();
data = new double[ ilist.size() ];
std::copy(ilist.begin(),ilist.end(),data);
}

Too many initializer values; Initializing Dynamically Allocated Arrays?

intArray is not an array, it's a pointer. A pointer can't be initialized with an initializer list.

Dynamic allocated memory can be initialized at the moment of allocation:

int* intArray = new int[8] {1, 2, 3, 4, 5, 6, 7, 8};

C array can be initialized also at the declaration:

int intArray[8] = {1, 2, 3, 4, 5, 6, 7, 8};

Can a C++11 initializer-list be used with a dynamic array?

Yes, the code is valid and value initializes each element of the array.

For standard references, refer to §5.3.4/17 [expr.new]

A new-expression that creates an object of type T initializes that object as follows:

...

— Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.

and then §8.5/7 [dcl.init]

To value-initialize an object of type T means:

...

— if T is an array type, then each element is value-initialized;

— otherwise, the object is zero-initialized.

The last bullet applies to each array element in this case.

Initializing a dynamic array with a raw array

This

Array array = {1, 2, 3, 4};

is not initializing using a raw array. this uses an initializer list or a uniform initializer. If you want to use a raw array, you must define it firstly, like what follows.

I used templates and passing by reference to deduce the size.

#include <iostream>
#include <algorithm>

struct Array {
size_t size;
size_t capacity;
int *ptr = nullptr;

template<size_t n>
Array(int (&arr) [n]):size{n}, capacity{2*size}, ptr{ new int[capacity]}{

std::copy(std::cbegin(arr), std::cend(arr), ptr);
}
~Array(){delete[] ptr;}
};

int main(){
int arr [] = {1, 2, 3, 4};
Array array = arr;
std::for_each(array.ptr, array.ptr+array.size, [](auto el){std::cout << el << " ";});
}

Demo

And this is another approach (using the uniform initializer), if you want to initialize your class as you showed

#include <iostream>
#include <algorithm>

struct Array {
size_t size;
size_t capacity;
int *ptr = nullptr;

template<class ... Args, class = std::enable_if_t<std::is_same_v<std::common_type_t<Args...>,int>>>
Array(Args ... args):size{sizeof...(Args)}, capacity{2*size},ptr{ new int[capacity]}{

int* temp = ptr;
((*(temp++) = args),...);
}
~Array(){delete[] ptr;}
};

int main(){
Array array = {1,2,3,4};
std::for_each(array.ptr, array.ptr+array.size, [](auto el){std::cout << el << " ";});
}

Demo

Using std::initializer_list<int>, it will be

#include <iostream>
#include <algorithm>

struct Array {
size_t size;
size_t capacity;
int *ptr = nullptr;

Array(std::initializer_list<int> && ls):size{ls.size()}, capacity{2*size},ptr{ new int[capacity]}{
std::copy(ls.begin(), ls.end(), ptr);
}
~Array(){delete[] ptr;}
};

int main(){
Array array = {1,2,3,4};
std::for_each(array.ptr, array.ptr+array.size, [](auto el){std::cout << el << " ";});
}

Demo

How can I initialize objects in a dynamically allocated array with some arguments

you can use std::vector.

If you still want to use arrays, you can use

Circle *arr = new Circle[5]{10}; which initializes first radius to 10 and use default for others.

Sample output will be:

radius : 10
radius : 0
radius : 0
radius : 0
radius : 0
deleted
deleted
deleted
deleted
deleted

If you want a single line solution you can use this dirty line:

Circle *arr = new Circle[5]{10,10,10,10,10};



Related Topics



Leave a reply



Submit