引用 unique_ptr 的向量

Vector with references to unique_ptr

我有 collection 个 unique_ptr。在这里,我想把其中的一些 return 交给来电者。调用者只需要读取内容,所以我想使用常量引用。但是我不确定如何使用 unique_ptrs.

来做到这一点

这是我用来使用原始指针执行此操作的一些代码:

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_ptrs 执行此操作?我也可以使用 shared_ptr,但所有权非常明确,正如我提到的,调用者不需要写权限。

std::vector包含的元素类型必须可赋值。引用不能是assigned-to(只能初始化)。


如果使用原始指针不是问题,因为调用者不参与所有权,您可以使用原始指针改为constentry

vector<const entry *> get_entries();

如果你想使用智能指针,你必须考虑将std::unique_ptr分配给std::shared_ptr会转移指针的所有权。也就是说,moved-from std::unique_ptr object 变为 empty:它不再拥有指针.

因此,您可能需要考虑将您的 collection 从 std::unique_ptr 完全过渡到 std::shared_ptr

The caller only needs to read the content

如果调用者不参与指针的所有权,那么就使用原始指针。其实裸指针可以认为是没有所有权的指针.

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;
}

如果你有一个 unique_ptr 的矢量,你想 return 一些给调用者,你可以迭代矢量并收集 raw另一个向量中的指针和 return 它。 使用智能指针约定时,一种有效的方法是使用 raw 指针进行读取,并使用 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;    
}

所以保持冷静,不要删除原始指针

根据 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;
}

唯一指针是 "value type" 包含一个指针。

因此您可以将其视为值类型。

但不可复制。因此,解决方案可能使用 const 引用。

这也不适用于 "vector" 类型。所以,解决方案是使用 reference_wrapper

//type alias for readability
using uEntry = std::unique_ptr<Entry>;

std::vector<uEntry> entries;

std::vector<std::reference_wrapper<const uEntry>> getEntries() {

    std::vector<std::reference_wrapper<const uEntry>> priventries;

    std::for_each(entries.begin(), entries.end(), [&](const uEntry &e) {
        if (e->a > 5) {
            priventries.push_back(std::cref<uEntry>(e));
        }
    });

    return priventries;
}

int main(int argc, const char * argv[]) {
    entries.push_back(uEntry(new Entry(5)));
    entries.push_back(uEntry(new Entry(7)));
    std::cout << getEntries().size();
    return 0;
}