将const共享指针的const向量返回给const对象

时间:2012-11-19 23:22:21

标签: c++ stl const shared-ptr

给定以下基于共享指针容器的类

class Foo;

class Bar {
public:
  // ...
  const std::vector<boost::shared_ptr<const Foo> >& getFoos() const { return foos_; }
private:
  std::vector<boost::shared_ptr<Foo> > foos_;
};

因为

而无法编译
invalid initialization of reference of type ‘const std::vector<boost::shared_ptr<const Foo>, std::allocator<boost::shared_ptr<const Foo> > >&’ from expression of type ‘const std::vector<boost::shared_ptr<Foo>, std::allocator<boost::shared_ptr<Foo> > >’

foos_成员需要指向Foo对象供内部使用的可变Bar对象,但我不希望客户端代码调用getFoos()能够修改任何东西。

const返回类型的Foo中删除getFoos()限定符可修复此问题。但是,我理解当std::vector将其常量传播到其元素时,boost::shared_ptr对它所指向的对象(自然地)没有这样的东西。因此,在我看来getFoos()不再观察其const限定符(即使编译器没有抱怨),因为客户端代码可以修改共享指针指向的Foo对象返回。

我说错了吗?如果是这样,是否有一些方法可以编写getFoos(),这样它就会返回const引用的const向量而不复制?

3 个答案:

答案 0 :(得分:3)

我可能错了,但我真的不认为你能做到这一点。

只有通过构建shared_ptr<Foo>

的新实例,

shared_ptr<const Foo>才能成为shared_ptr<const Foo>

shared_ptr<Foo>的引用不能成为shared_ptr<const Foo>的引用,只是因为它们是两种不同的类型。

在这里,您尝试将vector<shared_ptr<Foo>>引用为const vector<shared_ptr<const Foo>>的形式。

第一个const完全没问题。因为可以使用const限定符为同一引用类型分配引用。

但第二个const不是,因为您确实试图将对Type A向量的引用转换为对Type B向量的引用。

答案 1 :(得分:2)

而不是返回std::vector<...> const&,而是返回范围呢?范围是某种迭代器的pair。在这种情况下,您的迭代器将是std::shared_ptr<const foo>。您可以通过编写一个快速迭代器适配器来执行此操作,该适配器在内部迭代const_iteratorstd::shared_ptr<foo>,但返回std::shared_ptr<const foo>

您希望在const vector上执行的大部分操作都可以在range随机访问const_iterator上执行。

答案 2 :(得分:0)

您可以返回const shared_ptr<Foo>*指针而不是向量,并使用显式丑陋的C风格转换将foos_.data()转换为您想要的任何内容。

由于你对返回一个const向量感兴趣,当然除了调整大小信息之外,你不会因返回指针而损失太多。您始终可以将新指针包装在一个专门用于提供此大小调整信息的类中,如创建时提供的那样。