矢量与unique_ptr的引用

时间:2018-02-10 11:23:42

标签: c++ smart-pointers

我有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,但所有权非常明确,正如我所提到的,调用者不需要写访问权。

5 个答案:

答案 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_ptrstd::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;
}