给定以下基于共享指针容器的类
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向量而不复制?
答案 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_iterator
到std::shared_ptr<foo>
,但返回std::shared_ptr<const foo>
。
您希望在const
vector
上执行的大部分操作都可以在range
随机访问const_iterator
上执行。
答案 2 :(得分:0)
您可以返回const shared_ptr<Foo>*
指针而不是向量,并使用显式丑陋的C风格转换将foos_.data()
转换为您想要的任何内容。
由于你对返回一个const向量感兴趣,当然除了调整大小信息之外,你不会因返回指针而损失太多。您始终可以将新指针包装在一个专门用于提供此大小调整信息的类中,如创建时提供的那样。