在没有值初始化的情况下制作 std::unique_ptr 数组类型的推荐方法?
Recommended way to make std::unique_ptr of array type without value initialization?
我有一些 C++ 代码如下:
#include <memory>
void do_memory()
{
std::unique_ptr<int[]> ptr = std::make_unique<int[]>(50);
int* ptr2 = new int[50];
delete[] ptr2;
}
在第一种情况下,我创建了一个指向 int 数组的唯一指针,在第二种情况下,我分配了一个原始 int 数组。当范围离开时,两个数组都会被清理干净。玩弄这段代码(例如 https://godbolt.org/g/c3gEfV),我发现这两组指令的优化汇编是不同的,因为 make_unique
执行值初始化(具体来说,它似乎设置分配的所有值数组为 0)。所以 make_unique
引入了一些不必要的开销。
在没有自动值初始化的情况下,将unique_ptr
分配给数组(如上)的推荐方法是什么?我已经尝试过
std::unique_ptr<int[]> ptr = std::unique_ptr<int[]>(new int[50]);
但在我的应用程序中,我也有一个限制,即我在编译时不知道数组的大小,所以我不想分配任何具有(编译时)常量大小的数组.
如果确实需要,只需编写自己的函数即可:
template <typename T>
std::unique_ptr<T> make_unique_uninitialized(const std::size_t size) {
return unique_ptr<T>(new typename std::remove_extent<T>::type[size]);
}
避免直接创建 unique_ptr
的诱惑:
std::unique_ptr<T[]>(new T[size]) // BAD
因为这通常不是异常安全的(出于您首先使用 make_unique
的所有常见原因 - 考虑使用多个参数和抛出异常的函数调用)。
C++20 更新
C++20 引入了 std::make_unique_for_overwrite
,它的工作方式与 std::make_unique
类似,只是它执行默认初始化而不是值初始化。
我有一些 C++ 代码如下:
#include <memory>
void do_memory()
{
std::unique_ptr<int[]> ptr = std::make_unique<int[]>(50);
int* ptr2 = new int[50];
delete[] ptr2;
}
在第一种情况下,我创建了一个指向 int 数组的唯一指针,在第二种情况下,我分配了一个原始 int 数组。当范围离开时,两个数组都会被清理干净。玩弄这段代码(例如 https://godbolt.org/g/c3gEfV),我发现这两组指令的优化汇编是不同的,因为 make_unique
执行值初始化(具体来说,它似乎设置分配的所有值数组为 0)。所以 make_unique
引入了一些不必要的开销。
在没有自动值初始化的情况下,将unique_ptr
分配给数组(如上)的推荐方法是什么?我已经尝试过
std::unique_ptr<int[]> ptr = std::unique_ptr<int[]>(new int[50]);
但在我的应用程序中,我也有一个限制,即我在编译时不知道数组的大小,所以我不想分配任何具有(编译时)常量大小的数组.
如果确实需要,只需编写自己的函数即可:
template <typename T>
std::unique_ptr<T> make_unique_uninitialized(const std::size_t size) {
return unique_ptr<T>(new typename std::remove_extent<T>::type[size]);
}
避免直接创建 unique_ptr
的诱惑:
std::unique_ptr<T[]>(new T[size]) // BAD
因为这通常不是异常安全的(出于您首先使用 make_unique
的所有常见原因 - 考虑使用多个参数和抛出异常的函数调用)。
C++20 更新
C++20 引入了 std::make_unique_for_overwrite
,它的工作方式与 std::make_unique
类似,只是它执行默认初始化而不是值初始化。