2016-09-09 3 views
1

私はオペレータnewとdeleteをオーバーライドするための個人的なプロジェクトを完了し、プロセス内のアロケータクラスについて学びました。 cppreference.comを含むいくつかのオンラインリファレンスを読んで、私は多くの機能がオプションであると述べています。なぜ多くのアロケータ関数はオプションですか?

私の質問は、どのようにアロケータの受信者ですか? std::set、受け取ったアロケータがオプションで関数と型しか実装していない場合は動作しますか?

すべての関数のデフォルトの実装を持つ基本クラスから派生する必要があるのか​​どうかはわかりますが、割り当て子の継承要件はないようです。

また、コンパイルエラーによってこれらのオプション機能を実装する必要性が警告されるのはなぜですか?

参考として、ここで私がstd::setの3番目のテンプレート引数として使用したアロケータでの私の最初の試みです。私は既存の例を取り上げたので、私が実装したものの多くは不要かもしれないと思っていますが、将来他のSTLコンテナでアロケータを使うことを選択すると判断する方法はまだ分かりません。再度、コンパイルエラーに基づいてそれを理解することが期待されない限り...?

template <typename T> 
class Allocator // Custom allocator for use by AllocSet::mAllocatedPtrs to avoid infinite recursion 
{    // (because inserting an element in std::set calls ::operator new, which is overridden to add to AllocSet::mAllocatedPtrs). 
    public: 
     typedef T value_type; 
     typedef T* pointer; 
     typedef T& reference; 
     typedef const T* const_pointer; 
     typedef const T& const_reference; 
     typedef size_t size_type; 
     typedef ptrdiff_t difference_type; 

     template <typename U> 
     struct rebind { typedef Allocator<U> other; }; 

     Allocator() { } 
     template <typename U> Allocator(const Allocator<U>&) { } 
     virtual ~Allocator() { } 

     pointer allocate(size_t numT) { return (T*)(malloc(numT * sizeof(T))); } 
     void deallocate(pointer p, size_type st) { free(p); } 

     size_type max_size() { return size_type(-1); } 

     reference operator=(const_reference) { return *this; } 
     template <typename U> reference operator=(const Allocator<U>&) { return *this; } 
     template <typename U> bool operator==(const Allocator<U>&) { return true; } 
     template <typename U> bool operator!=(const Allocator<U>&) { return false; } 

     pointer address(reference r) { return &r; } 
     const_pointer address(const_reference r) { return &r; } 
}; 

答えて

4

私の質問はどのように割り当て先、例えばありますstd :: setは、受け取ったアロケータがオプションで関数と型を実装するだけであれば動作しますか?

あなたはthe allocator concecptを見れば:

いくつかの要件はオプションです:テンプレートのstd :: allocator_traitsはすべてオプション要件については、デフォルトの実装、およびすべての標準ライブラリのコンテナと他のアロケータ対応のクラスへのアクセスを提供しますアロケータはstd :: allocator_traitsを介して直接的ではありません。

これは、多くのことがオプションである理由でもあります - ほとんどのアロケータ実装は実際にはそれらを変更する必要がないので、どうして迷惑でしょうか?新しいメモリ再編成アルゴリズムのアイデアがあるとしたら、なぜpointerを定義する必要がありますか?


または1つは、コンパイルエラーが発生することにより、これらのオプション機能を実装する必要性を警告されるだろう推論ですか?

いいえ、アロケータのコンセプトはwell definedです。それはが提供するが何であるかを指定し、を提供します。コンパイルエラーに頼る必要はありません。

要件はthe standard、$ 17.6.3.5です。

+0

私は理解していると思います:ユーザが作成したアロケータに実装されていない限り、アロケータのユーザはデフォルトでstd :: allocator_traitsを使用します。もしそうなら、これは多型のように聞こえる。このアロケータのコンセプトがインターフェイス/実装のアプローチの代わりにこのように実装された理由をご存じですか? – StoneThrow

+0

@StoneThrowそうではありません:アロケータのユーザは無条件に 'std :: allocator_traits'を使うべきです。'std :: allocator_traits'は、アロケータが物事を提供するかどうかを判断するものです。例えば、[ここ](http://stackoverflow.com/questions/257288/is-it-possible-to-write-ac-template-to-check-for-a-functions-existence) max_size() 'が存在します。 –

+0

ありがとう、ありがとう。ここでも、クラスベースの多型の代わりにこのアプローチが採用された理由は何ですか?私は最近、テンプレートベースのコーディングに取り掛かっています。だから、賛否両論とそれを使用しないときの背後にある推論については興味があります。 – StoneThrow

関連する問題