【问题标题】:Exposing a vector of shared_pointers without giving ownership在不提供所有权的情况下公开 shared_pointers 的向量
【发布时间】:2020-01-02 10:43:09
【问题描述】:

我有一个包含共享指针向量的简单类:

class Bar {
public:
  /* stuff */
private:
  std::vector<std::shared_ptr<Foo>> foos;
};

我希望通过getFoos() 函数公开我的foos,该函数不会共享对象的所有权。一种方法是:

std::vector<std::reference_wrapper<Foo>> Bar::getFoos() const {
  std::vector<std::reference_wrapper<Foo>> fooRefs;
  fooRefs.reserve(foos.size());
  for (auto& ptr : foos) {
    fooRefs.push_back(std::ref(*ptr));
  }
  return fooRefs;
}

但这很丑。另外,我很可能需要缓存结果,因为这个函数经常被调用。更复杂,更丑陋。

有没有更清洁/更好的方法来处理这个问题?

【问题讨论】:

  • 为什么不const std::vector&lt;std::shared_pointer&lt;Foo&gt;&gt;&amp; getFoos() const { return foos; }?此时,这还不是共享所有权,而只是对原始的 const 引用。
  • 也许您可以提供一个名为Foo&amp; getFoo(std::size_t index); 的方法并通过它公开Foo?
  • std::vector&lt;std::weak_ptr&lt;Foo&gt;&gt; getFoos() 怎么样?

标签: c++ vector shared-ptr smart-pointers


【解决方案1】:

我将通过索引公开Foo,并提供获取迭代器的可能性

class Bar {
public:
  class FooIt {
    // Add typedefs for category etc
    std::vector<std::shared_ptr<Foo>>::iterator it; // maybe template on this to easily provide the const overload too
  public:
    Foo& operator*() const {
      return **it;
    }
    // write Functions to expose ++ etc of it
  };

  FooIt begin() {
    return FooIt{begin(foos)};
  }

  FooIt end() { 
    retuen FooIt{end(foos)};
  }
  // Enables ranged for over Bar, only do if that makes sense for your Bar

  Foo& getFoo(size_t index) { // maybe even operator [] if appropriate
    return foos[index];
  }
};

当然,这是很多样板。但实际上,如果您在多个地方遇到此问题,您可以将FooIt 写成一个通用的模板版本。

【讨论】:

  • 我喜欢这个解决方案。谢谢。
【解决方案2】:

可能是带有range-v3 的范围视图:

class Bar {
public:
  /* stuff */

     auto get_foos() const { return foos | ranges::views::indirect; }
private:
  std::vector<std::shared_pointer<Foo>> foos;
};

类似于您的std::vector&lt;reference_wrapper&gt;,但没有额外的向量。

views::indirect 给定可读值的源范围(例如指针或迭代器),返回一个新视图,该视图是取消引用每个值的结果。

也可以使用view::transform

【讨论】:

  • range-v3 也可用于 C++14。
猜你喜欢
  • 2018-01-23
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 2015-04-11
  • 2010-10-10
  • 2020-06-10
  • 2014-09-02
  • 2014-01-21
相关资源
最近更新 更多