2017-10-16 70 views
1

假設我有一個std::vector<std::string>如何爲分層分配類使用分配器

即使我爲矢量指定自定義分配器,我的std::string -s仍將使用標準字符串分配器。

我可以使用自定義分配器爲容器和容器共享嗎?

+0

我覺得這個問題太廣泛了。有3個單獨的問題:如何使用分配器爲簡單的類,如何使用分配器爲分層分配的類,以及如何編寫分配器知道的容器。所有這三個都是很大的問題。如果你知道第一個答案,我會建議第二個和第三個單獨的問題;如果你不知道第一個答案,那麼你應該先閱讀它(已經有很多答案)。 –

+1

我想問題是「如何使用分配器的分層分配類」將考慮如何編輯。 – Nick

回答

2

如果您有一個需要使用分層容器的分配器,標準庫提供了一個解決方案:scoped_allocator_adaptor。當您使用適配器時,它會強制該分配器向下傳遞給任何分配器識別的容器。這要求容器正確地將分配器感知的特徵專門化,並且它的所有構造函數都有一個使分配器持續的重載。下面是使用的例子從http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor

namespace bi = boost::interprocess; 
template<class T> using alloc = bi::adaptive_pool<T, 
            bi::managed_shared_memory::segment_manager>; 
using ipc_row = std::vector<int, alloc<int>>; 
using ipc_matrix = std::vector<ipc_row, std::scoped_allocator_adaptor<alloc<ipc_row>>>; 

有一點要注意的是,分配器是容器的類型,當然一部分。所以這不會讓你不需要爲內部容器指定正確的分配器類型。這是確保分配器實例被傳遞下來。這對於非無狀態的分配器很重要。這個例子繼續:

bi::managed_shared_memory s(bi::create_only, "Demo", 65536); 

// create vector of vectors in shared memory 
ipc_matrix v(s.get_segment_manager()); 

正如你可能得到這個分配器不是無狀態的。

如果你有一個無狀態的分配器,你不需要處理任何這種情況,你只需要定義外部和內部容器的類型來使用相同的分配器,那就是這樣。

我不會在這裏介紹它,但另一種方法是使用新的pmr方法來分配器。它沒有被合併到標準中。它確實使事情變得更簡單一些,因爲一切都被刪除了,我相信它會自動傳遞給嵌套的容器。如果你是谷歌,你可以在某處找到它的庫實現。

2

假設我有std :: string的std :: vector。我如何使用自定義分配器?我可以爲矢量做分配器,但是我還需要爲字符串做什麼?

當您爲容器使用自定義分配器時,您命令容器使用分配器分配內存。

容器不能負責它所包含的對象所執行的任何分配,所以是的,你也必須使用std::basic_string以及自定義分配器。

假設我有自己的類,類似於std :: string的鏈表。我如何使用自定義分配器?我應該自己執行還是說用malloc替換malloc等。

同樣,容器不應該負責/意識到其容器執行的分配!相反,使用std::basic_string自定義分配器。

scoped_allocator_adaptor

關於更新的問題,因爲尼爾弗裏德曼的回答表明,scoped_allocator_adaptor是使用相同的分配器的容器及其containees的標準解決方案。

這並不意味着容器負責集裝箱的分配,而是它們都共享相同的分配器。

+0

對不起,但這篇文章大多是不正確的。多級容器分配是已知的問題,並且在標準庫中有解決方案;你所建議的關注點分離並不是一個好的選擇。請參閱:http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor。 –

+0

@NirFriedman,請問您可以添加一些關於此事的參考鏈接? –

+1

我提供了一個到'scoped_allocator_adaptor'的鏈接。我認爲這足夠了? –