2012-11-19 60 views
4

鉴于基于共享指针的容器下面的类,返回常量的常量矢量共享指针为const对象

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_构件需要指向对Bar对象内部使用的可变对象Foo,但我不希望调用getFoos()的客户端代码能够修改任何内容。

getFoos()返回类型中,从Foo中删除const限定符可修复此问题。然而,据我所知,尽管std::vector将它的常量传播到它的元素,但boost::shared_ptr不会对它指向的对象(自然地)做这样的事情。因此,在我看来getFoos()不再遵守其const限定符(即使编译器不抱怨),因为客户端代码可以修改返回的共享指针所指向的Foo对象。

我正确吗?如果是这样,有没有办法写getFoos(),这样它会返回一个const引用的常量向量到const对象而不进行复制?

+0

一旦Bar的调用者获得了对它的引用,它会与'vector'一起做什么? –

+0

它应该*对其元素(或者更精确地说,对其元素指向的对象)执行只读操作。 – ezod

回答

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向量。

0

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

由于您有兴趣返回一个const向量,当然,您不会因返回一个指针而损失太多,除了大小调整信息。您可以始终将新指针包装在设计用于提供此尺寸信息的类中,并在创建时提供。

2

而不是返回一个std::vector<...> const&,那么返回一个范围呢?范围是某种类型迭代器的pair。在这种情况下,你的迭代器将会是std::shared_ptr<const foo>。您可以通过编写一个快速迭代器适配器来完成此操作,该适配器在内部迭代01​​至std::shared_ptr<foo>,但将其返回为std::shared_ptr<const foo>

您希望在constvector上执行的大多数操作都可以在随机访问const_iteratorrange上执行。