是否可以使用 std::make_unique 对动态数组进行大括号初始化?

ant*_*iok 5 c++ initialization smart-pointers unique-ptr c++11

通常,我们可以使用动态分配的大括号初始化来创建一个数组

int* arr = new int[5]{1,1,2,4,5};
Run Code Online (Sandbox Code Playgroud)

但这可以使用智能指针,特别是使用 std::make_unique 吗?我尝试过以下方法:

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});
Run Code Online (Sandbox Code Playgroud)

但没有用,而且我认为使用智能指针甚至不可能实现这一点。任何有关如何对智能指针使用大括号初始化的建议将不胜感激。

是的,我知道std::vector,但希望是否有其他方法。

JeJ*_*eJo 7

使用智能指针(特别是使用 )可以实现这一点吗std::make_unique

不,您不能使用 the ,std::make_unique因为它对数组有特殊的实现,并且它仅限于未知边界。

来自cppreference.com,对于未知边界std::make_unique只有过载2

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

Run Code Online (Sandbox Code Playgroud)
  1. 构造给定动态大小的数组。数组元素是值初始化的T仅当是未知边界的数组时,此重载才参与重载决策。

这意味着,在您的情况下,它会创建给定大小的动态数组,并且整数将被初始化为0,并且无法传递初始化值。


任何有关如何对智能指针使用大括号初始化的建议将不胜感激。

您可以不使用std::make_unique,例如:

std::unique_ptr<int[]> arr{ new int[]{1, 1, 2, 4, 5} };
Run Code Online (Sandbox Code Playgroud)

或者编写您自己的make_unique,这将创建您传递的元素类型的动态数组,并使用您传递的值进行初始化。

#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)... });
}
Run Code Online (Sandbox Code Playgroud)

现在你可以写:

std::unique_ptr<int[]> arr2 = make_unique_and_init(1, 1, 2, 4, 5);
Run Code Online (Sandbox Code Playgroud)

这是一个 工作示例代码