0

I have a dynamic array class, for which I would like to implement a functionality of initializing the dynamic array directly with a raw array, similar to std::vector.

struct Array {
   int *ptr = NULL;
   int size;
   int capacity;
   
   Array() : size(0), capacity(0) {}
   Array(int capacity) : size(0), capacity(capacity) {
       ptr = (int*)malloc(capacity*sizeof(int));
   }
};

We can initialize std::vector using a raw array like this:

 std::vector<int> v = {1, 2, 3, 4};

It seems that std::vector uses std::initializer_list to accomplish this. Is it possible to achieve the same result without using the STL library? Such that I can initialize it like this:

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

or

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

If this is not possible without std::initializer_list, how can I copy the elements from it to the dynamic array?

3
  • Consider reading a good C++ programming book, a good C++ reference website then using standard C++ containers such as std::array or std::vector Commented Aug 15, 2020 at 3:48
  • With recent GCC or Clang C++ compilers, the implementation of std::vector is open source, so study its source code. Commented Aug 15, 2020 at 3:50
  • Also, your ptr should better be initialialized with new and destroyed with delete Commented Aug 15, 2020 at 3:52

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

5 Comments

This is very helpful thank you! If that's actually an initializer list how could we initialize the class using it instead?
warning: ‘Array::size’ will be initialized after [-Wreorder]
Thank @asmmo, he did the heavy lifting. Nice solutions both.
@asmmo Awesome thanks very much! So template parameter packs is what I needed, didn't know about these! I'm guessing this is how std::initializer_list implemented also.
@LennyWhite "I'm guessing this is how std::initializer_list implemented also." - no. An initializer_list is a special kind of object that is constructed directly by the compiler itself while parsing user code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.