2011-12-19 7 views
7

はのは、私はSTLでリンクリストを作成しましょう:STLのカスタムアロケータは実際のデータのみを割り当てますか?

list<int, my_allocator<int> > data; 

それから私はのは、メモリプールを言わせて、より効率的なアロケータを使用することができます。しかし、リストをトラバースするために前方ポインタと後方ポインタのような内部メモリを割り当てる必要はありませんか?これらはどのように割り当てられますか?通常newを使用するか、なんとかmy_allocatorを使用しますか?

+0

選択したツールチェーンに同梱されているSTLまたはC++標準ライブラリ実装を意味しますか?それはどちらですか? –

+0

@ TomalakGeret'kal、何? (質問に+1) – avakar

+0

@avakar STLはもともとsgiプロジェクトでした。それ以来、STLのいくつかの実装(STLportなど)が行われており、そのほとんどが標準ライブラリに追加されていますが、いくつかの変更が加えられています。そのすべてが* "STL" *この質問に影響する可能性のある方法では少し曖昧です。 – dmckee

答えて

10

本当にコンテナは、独自の帳簿材料を割り当てるようにアロケータを再利用します。 (それはstd::listでは問題でしょうが、それは一般的には本当のこと*わけではありません。)標準アロケータ要件はrebindテンプレートの存在を義務付ける理由です:あなたのアロケータがAlloc = my_allocator<T>ある場合

typedef typename Alloc::template rebind<MyInternalStuff>::other internal_allocator; 

を、そしてinternal_allocatorはなりmy_allocator<MyInternalStuff>

これは、Electronic ArtsがC++標準ライブラリで持っていた厄介なものの1つだと私は信じています。その理由は、彼らのEASTLライブラリが厳密な制御を提供するアロケータに対して異なる規約を使用している理由です。

*)は、典型的には、各ノードは、いくつかのタイプNode<T>の1つのモノリシック対象となるので、私はstd::list<T, Alloc>のみこれまでアロケータとしてAlloc::rebind<Node<T>>::otherを使用すると仮定する。

[複数の編集で申し訳ありません。私は出力が絡み合い、正しく解釈しなかった。私は今、各容器を別々に印刷し、それに応じて出力を固定しました。 std::listは確かにだけアロケータを必要としない]


更新:をただ笑いのために、私は建設時に、独自の型名を印刷し、ほとんどのdemangle-アロケータを書きました。ここで入力があります:

#include <unordered_map> 
#include <set> 
#include <deque> 
#include <list> 
#include <vector> 
#include <map> 

#include <iostream> 

int main() 
{ 
    std::cout << "----- unordered_map<int, double> -----------" << std::endl; 
    std::unordered_map<int, double, std::hash<int>, std::equal_to<int>, funky_allocator<std::pair<const int, double>>> m { {1, 1.2} }; 
    std::cout << "----- set<int> -----------------------------" << std::endl; 
    std::set<int, std::less<int>, funky_allocator<int>> s; 
    std::cout << "----- deque<int> ---------------------------" << std::endl; 
    std::deque<int, funky_allocator<int>> d; 
    std::cout << "----- list<int> ----------------------------" << std::endl; 
    std::list<int, funky_allocator<int>> l; 
    std::cout << "----- vector<int> --------------------------" << std::endl; 
    std::vector<int, funky_allocator<int>> c; 
    std::cout << "----- map<int, bool> -----------------------" << std::endl; 
    std::map<int, bool, std::less<int>, funky_allocator<std::pair<const int, bool>>> n { { 1, true } }; 
} 

そして、ここで出力:

----- unordered_map<int, double> ----------- 
Default-construct: funky_allocator<std::pair<int const, double> > 
Copy-construct: funky_allocator<std::__detail::_Hash_node<std::pair<int const, double>, false> > 
Copy-construct: funky_allocator<std::__detail::_Hash_node<std::pair<int const, double>, false>*> 

----- set<int> ----------------------------- 
Default-construct: funky_allocator<std::_Rb_tree_node<int> > 

----- deque<int> --------------------------- 
Default-construct: funky_allocator<int> 
Copy-construct: funky_allocator<int*> 

----- list<int> ---------------------------- 
Default-construct: funky_allocator<std::_List_node<int> > 

----- vector<int> -------------------------- 
Default-construct: funky_allocator<int> 

----- map<int, bool> ----------------------- 
Default-construct: funky_allocator<std::_Rb_tree_node<std::pair<int const, bool> > > 

詳細が使用されるコンストラクタによって異なり:setmapなどのコンテナにのみ、いくつかの呼び出しで「正しい」アロケータを構築するかもしれません、他方では、指定されたアロケータのオブジェクトを最初に構築することができる。どちらの方法でも、指定されたアロケータは2つのコンテナで全く使用されず、のみリバウンドバージョンが使用されます。

+0

ありがとうございます; –

+0

+1、 'rebind'の前に' template'がありません:) – avakar

+0

@avakar:あなたはそうです、私は気づいたばかりです!実際には、インスタンス化時に独自のクラス名を表示して、いくつかの一般的なコンテナに必要ないくつかの異なるアロケータを確認する独自のデアントラリング・アロケータを書きました。 –

関連する問題