【问题标题】:Iterating over const T& in a std::vector<std::unique_ptr<T> >在 std::vector<std::unique_ptr<T> > 中迭代 const T&
【发布时间】:2014-09-04 15:14:13
【问题描述】:

我有这样的课程:

class RPNExpr
{
    std::vector<std::unique_ptr<Expr> > m_exprs;
};

m_exprs 的每个元素都由构建器函数在堆上分配,应该可以被其他类读取,但完全归 RPNExpr 所有,并且应该在 RPNExpr 超出范围时被销毁。

如果 m_exprs 的读者能够在 const Expr& 上获得迭代器,那就太好了,即隐藏向量持有 unique_ptrs 事实的迭代器。我希望这样做是为了与其他类保持一致,这些类将 unique_ptrs 保存到他们的数据中并返回 const T& 给他们。

这个界面可能类似于:

class RPNExpr
{
public:
    SomeIterator expr_begin();
    SomeIterator expr_end();
private:
    std::vector<std::unique_ptr<Expr> > m_exprs;
};

然后,消费者应该能够使用标准迭代器运算符来迭代 Expr。

有什么好办法吗?我应该编写一个抽象指针的向量包装器吗?我应该根本不这样做并在我的向量中使用 unique_ptrs 以外的东西吗?

【问题讨论】:

  • boost::ptr_vector 是合适的替代品吗?
  • @C.R.我想我可以使用 ptr_vector 并手动删除 ~RPNExpr 中的所有 Expr。我希望我能够避免使用 boost 并保持我的自动删除,但如果这不可能,这似乎是一个不错的选择,谢谢。
  • 我认为你可以定义你自己的迭代器类,它继承自默认迭代器,并在你取消引用它时返回一个 const T&。
  • @TartanLlama:boost::ptr_vector 假定所有成员指针的所有权,因此您不需要也不应该在 ~RPNExpr 中删除它们。为什么你希望避免提升?
  • @TartanLlama:我认为 vratojr 的意思是继承自 std::iterator,而不是 vector&lt;T&gt;::iterator

标签: c++ c++11 vector iterator unique-ptr


【解决方案1】:

在 boost 中有一个迭代器适配器可以做到这一点:

#include <boost/iterator/indirect_iterator.hpp>
...
using ExprIterator = boost::indirect_iterator<std::vector<std::unique_ptr<Expr>>::iterator>;
ExprIterator expr_begin() { return std::begin(m_exprs); }
ExprIterator expr_end() { return std::end(m_exprs; }

来源:http://www.boost.org/doc/libs/1_56_0/libs/iterator/doc/indirect_iterator.html

【讨论】:

  • 谢谢,这很好用。您甚至可以将 using typedef 模板化为具有通用 vector&lt;unique_ptr&lt;T&gt;&gt;->T&amp; 迭代器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2019-11-07
  • 2015-10-11
  • 2019-10-20
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多