Is it possible to use brace initialization of a dynamic array using std::make_unique?
Asked Answered
E

1

5

Typically, we can create an array using brace initialization of dynamic allocation by

int* arr = new int[5]{1,1,2,4,5};

But would this be possible using smart pointers, specifically using std::make_unique? I've tried the following:

unique_ptr<int[]> arr(5) {1,1,2,4,5};
unique_ptr<int[]> arr = make_unique<int[]>(5){1,1,2,4,5};
unique_ptr<int[]> arr = make_unique<int[]>({1,1,2,4,5});

But no avail, and I am getting to a point where I think this might not even be possible using smart pointers. Any suggestions on how to go about using brace initialization for smart pointers would be appreciated.

Yes, I am aware of std::vector but was hoping if there was a alternative way.

Eximious answered 15/10, 2021 at 7:9 Comment(0)
S
7

Would this be possible using smart pointers, specifically using std::make_unique?

No, you can not do with the std::make_unique as it has special implementation for the arrays, and it is restricted only for unknown bound.

From cppreference.com, for the unknown bound, std::make_unique has only the overload2

(only for array types with unknown bound)
template< class T >
unique_ptr<T> make_unique( std::size_t size ); (2) (Since C++14)

  1. Constructs an array of the given dynamic size. The array elements are value-initialized. This overload participates in overload resolution only if T is an array of unknown bound.

This means, in your case it creates the dynamic array of the given size and the integers will be initialized to 0, and can not pass the initialization values.


Any suggestions on how to go about using brace initialization for smart pointers would be appreciated.

You can do without the std::make_unique, something like:

std::unique_ptr<int[]> arr{ new int[]{1, 1, 2, 4, 5} };

or write your own make_unique which will create a dynamic array of the type of the elements you passed and initialized with the values you passed.

#include <memory>
#include <type_traits>  // std::common_type

template<typename... Args>
auto make_unique_init(Args&&... args)
{
    using Type = std::common_type_t<Args...>;
    return std::unique_ptr<Type[]>(new Type[sizeof...(args)]{ std::forward<Args>(args)... });
}

Now you can write:

std::unique_ptr<int[]> arr2 = make_unique_and_init(1, 1, 2, 4, 5);

Here is an working example code.

Syncretism answered 15/10, 2021 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.