2010-04-07 8 views
7

Das ist eine peinliche Frage, aber selbst die gut geschriebene Dokumentation, die mit boost.interprocess zur Verfügung gestellt wurde, hat mir nicht gereicht um dies zu tun.C++ - Allokatoren, insbesondere Übergabe von Konstruktorargumenten an Objekte, die boost :: interprocess :: cached_adaptive_pool zugeordnet sind

Was ich habe, ist ein cached_adaptive_pool allocator Instanz, und ich möchte es verwenden, um ein Objekt zu konstruieren, entlang Konstruktor Parameter übergeben:

struct Test { 
    Test(float argument, bool flag); 
    Test(); 
}; 

// Normal construction 
Test obj(10, true); 
// Normal dynamic allocation 
Test* obj2 = new Test(20, false); 

typedef managed_unique_ptr< 
    Test, boost::interprocess::managed_shared_memory>::type unique_ptr; 

// Dynamic allocation where allocator_instance == cached_adaptive_pool, 
// using the default constructor 
unique_ptr obj3 = allocator_instance.allocate_one() 
// As above, but with the non-default constructor 
unique_ptr obj4 = allocator_instance ... ??? 

Diese sehr gut ein Fehler meinerseits sein kann, wie man verwenden Allokator-Objekte im Allgemeinen. Aber auf jeden Fall kann ich nicht sehen, wie dieser spezifische Zuordner verwendet wird, wobei die in cached_adaptive_pool angegebene Schnittstelle Konstruktorargumente an mein Objekt übergeben muss.

cached_adaptive_pool hat die Methode: void construct(const pointer & ptr, const_reference v) aber ich verstehe nicht, was das bedeutet und ich kann keine Beispiele finden, die es verwenden.

Mein Kopf hat den ganzen Tag in Vorlagen geschwommen, so dass eine helfende Hand, auch wenn die Antwort offensichtlich ist, sehr geschätzt wird.

Antwort

1

cached_adaptive_pool hat die Methode: Leere Konstrukt (const Zeiger & ptr, const_reference v), aber ich verstehe nicht, was das bedeutet, und ich kann nicht Beispielen es finden.

Es sollte die Schnittstelle von std::allocator, in welchem ​​Fall allocate() gibt Ihnen ein geeignetes Stück nicht initialisierten Speicher und construct() Anrufe Platzierung neu auf dem gegebenen Zeiger folgen.

Etwas wie:

allocator_instance.construct(allocator_instance.allocate_one(), Test(30, true)); 

diejenigen Pools selbst, wenn auch nicht verwendet. In C++ 0x sollten Zuweiser in der Lage sein, jeden Konstruktor und nicht nur den Kopierkonstruktor aufzurufen, daher könnte es sein, dass die Zuweiser von Boost dies bereits zu einem gewissen Grad unterstützen.

a.construct(p, 30, true); //a C++0x allocator would allow this and call new (p) Test(30, true) 
+0

Danke. Die erste Form ist die Art von Antwort, die ich erwartete, aber war zu verwirrt und müde, um mich selbst zu erkennen. Die zweite Form "a.construct (p, 30, true)" scheint von diesem speziellen Boost-Allokator nicht unterstützt zu werden. Ärgerlich genug, da 'cached_adaptive_pool.construct()' '' void' zurückgibt, muss ich 'allocator_t :: pointer obj = allocator.allocate_one(); allocator.construct (obj, Test (30, wahr)) '? Ich bin mir nicht sicher, was noch schlimmer ist, zwei Anweisungen für eine einfache Operation zu verwenden oder eine etwas seltsam aussehende neue Platzierung direkt zu verwenden. – porgarmingduod

+0

Sie könnten das eine separate Funktion machen. – UncleBens

1

Ich denke, ich kann immer Platzierung neue Syntax verwenden. Die Idee besteht darin, den intelligenten Zeiger (in diesem Fall offset_ptr), der vom Zuordner zurückgegeben wird, zu dereferenzieren und dann die unformatierte Adresse an new() zu übergeben.

unique_ptr obj = new(&(*allocator_instance.allocate_one())) Test(1,true) 

Ist das der idiomatische Weg, dies zu tun? Es gibt so viele andere Orte in Boost, wo explizite Unterstützung angeboten wird, um die Verwendung von Placement neu zu vermeiden, was mich dazu bringt, nicht zu denken. In jedem Fall werde ich diese Antwort akzeptieren, wenn in naher Zukunft nichts Besseres zur Verfügung steht.

+0

Für was ist die '& * ptr' Sequenz? – UncleBens

+0

Wenn ich es getestet habe, würde new nur einen rohen Zeiger akzeptieren, nicht einen offset_ptr, den dieser Zuordner zurückgibt. – porgarmingduod