2012-11-19 90 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上執行。