我有unique_ptr
的集合。在这里,我想采取其中一些并将它们返回给调用者。调用者只需要读取内容,所以我想使用常量引用。但我不确定如何使用unique_ptr
s。
以下是我使用原始指针执行此操作的一些代码:
class entry
{
};
vector<entry*> master;
const vector<entry*> get_entries()
{
vector<entry*> entries;
// peusocode, master contains all entries.
// only some entries are copied, filtered by some predicate
copy_if(master.begin(), master.end(), back_inserter(entries), ...);
}
如何使用unique_ptr
执行此操作?我也可以使用shared_ptr
,但所有权非常明确,正如我所提到的,调用者不需要写访问权。
答案 0 :(得分:2)
来电者只需要阅读内容
如果调用者不参与指针的所有权,那么只需使用原始指针。实际上,原始指针可以被视为没有所有权的指针。
std::vector<std::unique_ptr<entry>> master;
std::vector<const entry*>
get_entries()
{
std::vector<const entry*> entries;
for ( auto const &ptr : master ) {
/* if something satisfied */
entries.push_back(ptr.get());
}
return entries;
}
答案 1 :(得分:2)
唯一指针是包含指针的“值类型”。
因此,您可以将其视为值类型。
但这是不可复制的。因此,解决方案可能使用const引用。
这也不能应用于“矢量”类型。因此,解决方案是使用reference_wrapper
vector<unique_ptr<Entry> > entries;
vector<std::reference_wrapper<const unique_ptr<Entry> > > getEntries() {
vector<std::reference_wrapper<const unique_ptr<Entry> > > priventries;
for_each(entries.begin(), entries.end(), [&](const unique_ptr<Entry> &e){ if (e->a > 5) {
priventries.push_back(std::cref<unique_ptr<Entry> >(e));
} });
return priventries;
}
int main(int argc, const char * argv[]) {
entries.push_back(unique_ptr<Entry>(new Entry(5)));
entries.push_back(unique_ptr<Entry>(new Entry(7)));
cout << getEntries().size();
return 0;
}
答案 2 :(得分:1)
std::vector
包含的元素类型必须可分配。参考文件不能分配给(仅初始化)。
如果使用原始指针不是问题,因此调用者不参与所有权,您可以使用原始指针来 { {1}} const
代替:
entry
如果您想使用智能指针,则必须考虑将vector<const entry *> get_entries();
分配给std::unique_ptr
将转移指针的所有权。也就是说,移动的 std::shared_ptr
对象变为为空:它不再拥有指针。
因此,您可能需要考虑从std::unique_ptr
到std::unique_ptr
的完整转换。
答案 3 :(得分:1)
如果你有一个unique_ptr的向量,并且想要将其中一些返回给调用者,你可以迭代向量并在另一个向量中收集原始指针并返回它。 使用智能指针约定时的一个有效方法是使用原始指针进行读取,并将unique_ptr和shared_ptr留给内存管理
vector<entry*> collect(const vector<unique_ptr<entry>>& data){
vector<entry*> result;
for (auto const & it: data){
if (ShouldBeCollected()){
result.push_back(it.get())
}
}
return result;
}
所以保持冷静,不要删除原始指针
答案 4 :(得分:1)
根据OP的情况,解决方案必须如下所示。我向OP提出他将如何申请std::copy_if
。
#include <memory>
#include <vector>
#include <algorithm>
class entry {
};
std::vector<std::unique_ptr<entry>> master;
std::vector<const entry*> get_entries()
{
std::vector<const entry*> entries;
// only some entries are copied, filtered by some predicate
std::transform(master.begin(), master.end(), std::back_inserter(entries),
[](const auto& up){return up.get();});
return entries;
}