传递唯一ptr的向量



我的代码看起来像:

vector<unique_ptr<Foo>> foos = ... // Init vector.
// Do some stuff.
func(std::move(foos)); // func should now own foos, I'm done with them.
// Takes ownership of foos.
void func(vector<unique_ptr<Foo>>&& foos);

现在,在func中,我想将一些代码重构为一个需要使用foos的单独函数。我想知道怎么做。我考虑的选项是:

void util_func1(const vector<Foo*>& foos); // Does not take ownership of foos
void util_func2(const vector<unique_ptr<Foo>>& foos); // Does not take ownership of foos

第一个选项似乎与unique_ptr(非向量(的建议一致,如果函数拥有所有权,则通过值传递unique_ptr.如果函数不拥有所有权,通过原始ptr/ref传递。如果我理解正确,建议永远不要通过const-ref传递unique_ptr。这基本上就是util_func2正在做的事情。

我的问题是现在func变得相当丑陋:

void func(vector<unique_ptr<Foo>>&& foos) {
vector<Foo*> raw_ptr_foos;
raw_ptr_foos.reserve(foos.size());
for (auto foo : foos) raw_ptr_foos.push_back(foo.get());
util_func1(raw_ptr_foos);
}

那么util_func2是正确的方法吗?还是我应该咬紧牙关,把丑陋的转换写成raw_ptr_foos?还是有第三种方法?

如果您有C++20,您可以将其表示为概念,并使用受约束的模板作为辅助对象。

template <typename P, typename T>
concept points_to = requires(P p) {
{ *p } -> std::common_reference_with<T &>
} && std::equality_comparable_with<std::nullptr_t>
template <std::ranges::borrowed_range R, typename T>
concept indirect_range_of = points_to<std::ranges::range_value_t<R>, T>;
template <indirect_range_of<Foo> Foos>    
void util_func1(Foos foos);
void func(std::vector<std::unique_ptr<Foo>> foos) {
util_func1(std::ranges::views::all(foos));
}

在此之前,您编写了一个模板,并可以选择添加sfinae或static_asserts

template <typename Foos
void util_func1(const Foos & foos);
void func(std::vector<std::unique_ptr<Foo>> foos) {
util_func1(foos);
}

如果您想在多个函数中访问和更改这些向量元素,我会考虑使用shared_ptrs而不是unique_ptrs。这样,您仍然不必担心函数执行结束时的内存泄漏,也不必处理原始指针。

最新更新