Std::unique_ptr支持数组,例如:

std::unique_ptr<int[]> p(new int[10]);

但这是必要的吗?可能使用std::vector或std::array更方便。

你觉得这个结构有什么用处吗?


当前回答

我遇到了一个情况,我必须使用std::unique_ptr<bool[]>,它位于HDF5库(用于高效二进制数据存储的库,在科学中使用很多)中。一些编译器(在我的例子中是Visual Studio 2015)提供std::vector<bool>的压缩(通过在每个字节中使用8个bool),这对于HDF5之类的东西来说是一个灾难,它不关心这种压缩。对于std::vector<bool>, HDF5最终会因为压缩而读取垃圾。

猜猜谁在那里进行救援,在std::vector不起作用的情况下,我需要干净地分配一个动态数组?: -)

其他回答

std::vector可以被复制,而unique_ptr<int[]>允许表示数组的唯一所有权。另一方面,Std::array要求在编译时确定大小,这在某些情况下可能是不可能的。

您可能使用unique_ptr的一个原因是,如果您不想支付初始化数组值的运行时成本。

std::vector<char> vec(1000000); // allocates AND value-initializes 1000000 chars

std::unique_ptr<char[]> p(new char[1000000]); // allocates storage for 1000000 chars

// C++20 version:
auto p = std::make_unique_for_overwrite<char[]>(1000000);

std::vector构造函数和std::vector::resize()将对t进行值初始化,但new和std::make_unique_for_overwrite将默认初始化它们,这对于PODs来说意味着什么都不做。

参见c++ 11中的值初始化对象和std::vector构造函数

注意,vector::reserve在这里不是一个替代方案:在std::vector::reserve之后访问原始指针是安全的吗?

这和C程序员选择malloc而不是calloc的原因是一样的。

为了回答人们认为你“必须”使用vector而不是unique_ptr,我在GPU上的CUDA编程中有一个案例,当你在Device中分配内存时,你必须使用一个指针数组(使用cudaMalloc)。 然后,当在Host中检索该数据时,必须再次寻找指针,unique_ptr可以很容易地处理指针。 将double*转换为vector<double>的额外成本是不必要的,并且会导致性能损失。

当你只能通过一个现有的API(窗口消息或线程相关的回调参数)插入一个指针时,它们可能是正确的答案,这些指针在被“捕捉”到另一边后具有一定的生命周期,但与调用代码无关:

unique_ptr<byte[]> data = get_some_data();

threadpool->post_work([](void* param) { do_a_thing(unique_ptr<byte[]>((byte*)param)); },
                      data.release());

我们都希望事情对自己有利。c++是其他时候用的。

与std::vector和std::array相反,std::unique_ptr可以拥有一个NULL指针。 这在使用期望数组或NULL的C api时非常方便:

void legacy_func(const int *array_or_null);

void some_func() {    
    std::unique_ptr<int[]> ptr;
    if (some_condition) {
        ptr.reset(new int[10]);
    }

    legacy_func(ptr.get());
}