3

私は Visual Studio 2008 C++ アプリケーションを使用しており、std::vector. しかし、私は問題に遭遇しました。私の実装は、リソースへのハンドルを所有するアロケータに依存しています。この機能を使用する場合rebind、ハンドルの所有権を新しいアロケーターに譲渡する必要があります。このようなもの:

template< class T >
class MyAllocator
{
public:
    template< class U >
    explicit MyAllocator( const MyAllocator< U >& other ) throw() 
        :  h_( other.Detach() ) // can't do this to a `const`
    {
    };

    // ...

private:
    HANDLE Detach()
    {
        HANDLE h = h_;
        h_ = NULL;
        return h;
    };

    HANDLE h_;
}; // class MyAllocator

残念ながら、古いアロケーターのハンドル所有権を解放することはできませんconst。rebind コンストラクターから削除するconstと、コンテナーはそれを受け入れません。

error C2558: class 'MyAllocator<T>' : no copy constructor available or copy constructor is declared 'explicit'

この問題を回避する良い方法はありますか?

4

4 に答える 4

2

アロケータについてあまりよく知らなくても(必要になることはありません):コピーコンストラクタはconstrefを受け取るため、オブジェクトを変更しないことを約束しotherますが、とにかく変更しようとします。クラスがそのように設計されている場合もありますが(std::auto_ptr)、これは怪しいようです。
構文的には、いつでも宣言してメンバー関数h_ mutableを作成できますが、ブロードソードを使用して構文ジャングルをハッキングする前に、このセットアップのセマンティクスに真剣に疑問を投げかけます。Detach()const

于 2011-05-09T19:33:23.477 に答える
1

これは、余分なレベルの間接化で解決できますが、理想的な解決策ではありません。基本的に、アロケータには、コンストラクタ/デストラクタで割り当て/割り当て解除されるハンドルへのポインタがあります。それが指すハンドルは一貫して非定数であるため、あるアロケーターから別のアロケーターにハンドルを「移動」できます。ただし、これにより、アロケーターにいくらかのオーバーヘッドが追加されます。

あなたの正確なケースはわかりませんが、自明ではないコピー可能なステートフルアロケーターは、そのすべての意味について慎重に検討する必要があるようです。移動専用ハンドルを持たないように設計を単純化できる別の方法はありますか?

于 2011-05-12T13:01:58.780 に答える
1

h_として宣言するとどうなりますmutableか?

于 2011-05-09T18:58:41.563 に答える
1

所有権を譲渡することはできません。これは、アロケーターが 1 つのコンテナー内でも複数回コピーおよび再バインドされ、結果のインスタンスが同時に使用される可能性があるためです。

代わりに、リソースを共有する必要があります。参照カウントを使用してリソースの間接化を作成します。何かのようなもの:

class SharedHandle {
    HANDLE h_;
    int count;
    SharedHandle(HANDLE h) : h_(h), count(1) {}
    ~SharedHandle() { CloseHandle(h_); } // or whatever to release the resource.
    SharedHandle *Ref() { ++count; return this; }
    void Unref() { if(!--count) delete this; }
}

そしてより:

explicit MyAllocator( const MyAllocator< U >& other ) throw() 
:  h_( other.h_->Ref() )

hash_map/のような異種ブロックを自然に割り当てる必要があるコンテナーに加えてunordered_map、Microsoft のコンテナーの実装では、さまざまな奇妙なものを割り当てることが知られています。ある Windows アプリケーションで割り当てを追跡したところ、STL 内のどこかから発生した奇妙なサイズの割り当てが多数ありました。

于 2011-05-12T13:32:32.523 に答える