将向量<int>转换为常量 unique_ptr<const int[]>



如何将矢量转换/复制到unique_ptr<int[]>

这正是我想要实现的(向量源自另一个上下文,在复制到unique_ptr后将被删除。unique_pr是固定长度的,因此可以更有效地分配(。

std::vector<int> vv {1, 2, 3};
struct
U {
U(std::vector<int> v) { // copy constructor
// copy vector v to unique_ptr u, HOW?
}
std::unique_ptr<int[]> u; 
};

U uu {vv}; // copy vector vv to unique_ptr uu, HOW?

我试图制作一个复制构造函数

U(std::vector<int> v) {
u = std::make_unique<int[]>(v.size()); // OK
std::copy(v.begin(), v.end(), u); // error: u has no copy constructor
}

那么,我应该如何构造复制构造函数呢?

事实上,而且,一旦构建,我想要unique_ptr<T[]>长度和内容都是恒定的,所以在我的情况下,它应该是

std::unique_ptr<int const[]> const u; // const in both length and content

复制构造函数在这两种情况下看起来如何?

情况1(std::unique_ptr<int[]>u情况2(std::unique_ptr<int const[]>const u

您所做的工作有几个问题。首先,您有两个副本,而不是一个副本(在U构造函数中(,然后因为您需要在u上获得实际的迭代器,而不是u本身。

为了常量的正确性,您可以只使用一个中间的唯一指针来更改数据。

你的最终代码应该是这样的:

struct U {
U(const std::vector<int>& v) {
auto data = std::make_unique<int[]>(v.size());
std::copy(v.begin(), v.end(), data.get());
u = std::move(data);
}
std::unique_ptr<int const[]> u; 
};

需要注意的是:向量的效率和你唯一的指针一样高。数据访问模式将是相同的。只有当您将其推回或擦除时,才会产生开销。由于您没有执行任何这些操作,因此只需存储一个const vector

如果您想要const std::unique_ptr<int const[]> u,那么您需要添加一个static方法,该方法将把您的向量转换为std::unique_ptr<int const[]>,并且您的构造函数将在其上使用&&,并将其移动到init列表中的u中。

struct U {
U(std::unique_ptr<int const[]>&& u)
: u(std::move(u)) {}
static U create(const std::vector<int>& v) {
auto data = std::make_unique<int[]>(v.size());
std::copy(v.begin(), v.end(), data.get());
std::unique_ptr<int const[]> u = std::move(data);
return U(std::move(u));
}
const std::unique_ptr<int const[]> u; 
};

我试图制作一个复制构造函数

这不是一个复制构造函数。这是一个转换构造函数。

std::copy(v.begin(), v.end(), u); // error: u has no copy constructor

std::copy的第三个参数必须是迭代器,就像前两个一样。std::unique_ptr不是迭代器。

唯一指针指向一个数组。指针是数组的迭代器。所以,你需要的是一个指针。如何从唯一指针中获取指针?使用std::unique_ptr::get成员函数。

通过接受模板迭代器(或范围(而不是向量,可以使构造函数更加通用。作为奖励,您可以避免复制两次(也可以通过使用引用来避免(。

unique_ptr具有固定长度,因此可以更有效地分配

向量和动态数组(如由唯一指针管理的数组(的分配方式几乎没有区别。即使有一些差异,复制输入矢量进行转换的效率也会比不复制低得多

最新更新