2014-12-03 78 views
5

我想要一些等價於C++ std :: vector的東西,其中底層對象是不可變的。所以我可以通過push_back()項將它們添加到向量中,等等。一個實際的std :: vector維護一個數組,該數組的大小大於向量的大小,填充了默認的構造對象,當你使用push_back()時,它對數組中元素的賦值。我的不可變對象沒有默認的構造函數,並且賦值是一個變異操作,所以也是如此。C++中的不可變對象的可變容器

我可以做一個vector<boost::optional<T>>,但是這是一個雜亂的接口,因爲我只希望把有效構造的對象爲載體,只有讓那些走出載體。

我以爲提升有這樣的東西,但我找不到它。有這樣的事情存在嗎?

+2

至少在C++ 11中,向量按照您希望的方式工作。你可以使用'emplace_back()'。 – 2014-12-03 19:07:08

+0

你能否將智能指針存儲到向量中的實際不可變對象? – shuttle87 2014-12-03 19:07:28

+1

你描述的方式'矢量'不完全匹配它的工作方式。你的類型是否有移動和/或複製構造函數? – hvd 2014-12-03 19:07:29

回答

4

您對vector工作原理的看法不正確。

該向量使用分配器分配原始內存。原始內存而不是包含默認的構造對象 - 它只是原始內存。

當您執行push_back(例如)時,它會使用一個放置new將對象構建到原始內存中。同樣,當你使用一個對象時,它最終會直接調用它的析構函數把對象轉換回原始內存。

使用當前(C++ 11或更高版本)實現std::vector,您的對象不需要支持默認構造或分配。支持移動建設和移動分配應該足夠了。要使用它們,您可以使用emplace_back而不是push_back

+0

右值'push_back()'也使用移動構造。 – Angew 2014-12-03 19:37:26

+1

@Angew:對。同樣,如果您的類型不支持移動,'emplace_back'可以複製副本 - 但我更願意使用代碼來反映真實的意圖,所以如果您計劃使用移動類型,我寧願即使'push_back'實際上可以工作,請參閱'emplace_back'。 – 2014-12-03 19:46:29

+0

好吧,我喜歡「代碼你的意思」的思路,所以這是非常有道理的。 – Angew 2014-12-03 20:31:42