2009-10-21 8 views
8

Ich möchte verschiedene Instanzen einer benutzerdefinierten STL-Zuweisungsklasse verwenden, um unterschiedliche Speicherbereiche zu verwalten, und dann eine Zuweisungsinstanz für einen STL-Container angeben können, von der jeder Container nur abruft sein zugewiesener Speicherplatz. Aber ich sehe nicht, wie ich das machen kann. Ich sehe, wie ich einen Zuordnertyp in die Template-Parameter eines STL-Containers übergeben kann, aber ich möchte etwas Ähnliches wie die Übergabe einer Zuweisungsinstanz in den Konstruktor eines STL-Containers. Gibt es eine Möglichkeit, dies in STL zu tun?Benutzerdefinierte STL-Zuordner zum Verwalten unterschiedlicher Speicherbereiche

Antwort

17

Leider können STL-Zuordner keinen Status haben (oder müssen zumindest sehr vorsichtig sein, wie dieser Status verwendet wird) - jede Instanz eines bestimmten Zuordnungstyps muss äquivalent sein, damit STL-Container effektiv mit ihnen arbeiten können. Ich erinnere mich nicht an die Details im Moment, aber ich weiß, dass Scott Meyers ausführlich über dieses Problem in "Effective STL", Punkt 10 spricht: Beachten Sie die Konventionen und Einschränkungen des Zuweisers.

aber Sie können haben Verteilern Templat, die sehr ähnlich sind mit den Unterschieden zwischen den Zuweiser im allocator Typ eingekapselt ist und verschiedene ‚instantiations‘ der allocator Vorlage verwenden (jede Vorlage ‚Instanziierung‘ ist eine andere Art) . Meine Erinnerung ist wieder, dass Meyers das ziemlich deutlich diskutiert.

Zum Beispiel diesen Absatz aus einem Artikel von Anthony Aue, "Improving Performance with Custom Pool Allocators for STL" sehen:

Ein potenziell ernsten Nachteil ist, dass, da das allocator nicht statische Daten verwendet, es konform, da der Standard, der von den gleichen Verteilern erfordert nicht technisch Norm ist Geben Sie Äquivalent ein. Eine ausführliche Erläuterung des Problems finden Sie unter Effektive STL (Punkt 10). Dies erfordert, dass ein Zuordner für einen gegebenen Typ in der Lage ist, Speicher freizugeben, der von irgendeiner anderen Instanz eines Zuweisers für diesen Typ zugeteilt wurde. Für viele Verwendungen von Standardcontainern ist diese Anforderung nicht notwendig (manche sagen drakonisch). Es gibt jedoch zwei Fälle, in denen diese Anforderung unbedingt erforderlich ist: list :: splice und swap(). Der Fall von swap() ist besonders gravierend, da er benötigt wird, um bestimmte Operationen an Containern in einer ausnahmesicheren Weise zu implementieren (siehe Exceptional C++, Punkt 12). Technisch könnte Swap (angesichts von Allokatoren, die nicht gleichwertige Elemente vergleichen können) implementiert werden (und in einigen Fällen auch umgesetzt werden), oder die Allokatoren könnten zusammen mit den Daten ausgetauscht werden - dies ist jedoch nicht immer der Fall. Wenn Sie also swap() oder list :: splice verwenden, sollten Sie sicherstellen, HoldingPolicySingleton zu verwenden; Andernfalls werden Sie in ein ziemlich unangenehmes Verhalten geraten.

Siehe auch Stephan T. Lavavejs Diskussion in this newsgroup thread.

Ich werde später später aktualisieren, wenn jemand anderes die Details in der Zwischenzeit nicht gibt.

+2

Es ist jedoch erwähnenswert, dass C++ 0x Unterstützung für ungleiche Zuordner erfordert. –

+1

Sie haben Recht, das ist erwähnenswert - Stroustup's FAQ zu C++ 0x "Scoped Allocators": http://www.research.att.com/~bs/C++0xFAQ.html#scoped-allocator –

+0

+1 - Ich wünschte, ich könnte diese Antwort mehr auf die Probe stellen. Die Allokatoren in STL waren ziemlich noob-feindselig - sie zogen mehr esoterische Bugs an, als dass sie Funktionalität beisteuerten. – Fox

0

Vielleicht könnten Sie einen Satz von Zuordnungstypen codieren, der ein statisches Aufzeigen auf separate Speicherbereiche enthält.

Wenn der STL-Container dann seinen Zuordner erstellt, verwendet der Zuordner den Speicherplatz, der diesem Zuordner zugewiesen ist.

Der Einfachheit halber wird angenommen, dass Sie zwei Speicherbereiche verwenden möchten. Erstellen Sie zwei Zuordnungstypen, einen für jeden Speicherplatz. Übergeben Sie den Zuordnungstyp den STL-Containerkonstruktoren nach Bedarf.

6

Mit den STL-Containern können Sie den Zuordner als Argument für den Konstruktor übergeben.

Zum Beispiel sind hier die entsprechenden Konstrukteure für Vektor:

explicit vector(const Allocator& = Allocator()); 
explicit vector(size_type n, const T& value = T(), 
    const Allocator& = Allocator()); 
template <class InputIterator> 
vector(InputIterator first, InputIterator last, 
    const Allocator& = Allocator()); 

standardmäßig verwenden sie nur eine Standard aufgebaut allocator.

Verwandte Themen