如何确保返回向量的常量<unique_ptr> </unique_ptr>

时间:2014-08-29 04:20:14

标签: c++ c++11

我问过相关问题here。现在它有点微妙。

以下是代码:

class MyClass {
  public:
    const vector<unique_ptr<MyObject> >& get_const_objs() const;

  private:
    vector<unique_ptr<MyObject>> m_objs;
};

我的意图是来自get_const_objs()的返回向量是只读的,但问题是因为向量的元素不是const,所以调用者仍然可以更改单个元素,例如。

const vector<unique_ptr<MyObject>>& objs = pMyClass->get_const_objs();
unique_ptr<MyObject> p = move(objs[0]);

我的解决方案是将const插入向量:

const vector<const unique_ptr<MyObject> >& get_const_objs() const;

但是这导致了一个无聊的get_const_objs()实现,我将每个元素复制到一个新的向量:

const vector<const unique_ptr<MyObjects>>& MyClass::get_const_objs() const
{
  vector<const unique_ptr<MyObjects>> ret;
  for (const auto &obj : my_objs) {
    ret.push_back(obj);
  }
  return ret;
}

是的,我可以在MyClass中添加迭代器接口。还有其他解决方案吗?

我有一个限制:BOOST不可用。但我喜欢知道BOOST解决方案,如果真的有一个好的只使用标准。

3 个答案:

答案 0 :(得分:1)

一个(小)更好的解决方案是返回std::vector<const MyObject*>而不是公开std::unique_ptr

std::vector<const MyObject*> get_const_objs() const
{
    std::vector<const MyObject*> res;
    res.reserve(my_objs.size());
    for (const auto& obj : my_objs) {
        res.push_back(obj.get());
    }
    return res;
}

您可以将此向量作为成员,而不是每次都重新创建向量,但是您需要保持向量同步。

答案 1 :(得分:1)

const vector<unique_ptr<MyObject>>& objs = pMyClass->get_const_objs();
unique_ptr<MyObject> p = move(objs[0]);

You cannot do it,所以你不必担心!

由于objsconst vector<> &,此向量的元素也会被视为const。因此,你不能移动&#34;它;你可以移动const对象吗?

答案 2 :(得分:0)

自定义迭代器似乎是最简单的方法,只需公开一个解除引用到const MyObject&amp;

的迭代器
class ConstObjectIter {
public:
    ...
    const MyObject& operator* () const { return **m_it; }
    const MyObject* operator->() const { return &**this; }
    ConstIter& operator++() { ++m_it; return *this; }
    ...
private:
    std::vector<std::unique_ptr<MyObject> >::const_iterator m_it, m_end;
}

使用m_it, m_end resp。

初始化m_objs.begin(), m_objs.end()