2010-04-07 10 views
7

Esta es una pregunta embarazosa, pero incluso la documentación bien escrita provista con boost.interprocess no ha sido suficiente para que descubra cómo para hacer esto.Asignadores de C++, pasando específicamente argumentos de constructor a los objetos asignados con boost :: interprocess :: cached_adaptive_pool

Lo que tengo es una instancia cached_adaptive_pool asignador, y quiero utilizarlo para construir un objeto, pasando a lo largo parámetros del constructor:

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 ... ??? 

esto puede muy bien ser un fracaso de mi parte sobre el uso de objetos asignador en general. Pero en cualquier caso, no puedo ver cómo usar este asignador específico, con la interfaz especificada en cached_adaptive_pool para pasar argumentos de constructor a mi objeto.

cached_adaptive_pool tiene el método: void construct(const pointer & ptr, const_reference v) pero no entiendo lo que eso significa y no puedo encontrar ejemplos para usarlo.

Mi cabeza ha estado nadando en plantillas todo el día, por lo que una mano amiga, incluso si la respuesta es obvia, será muy apreciada.

Respuesta

1

cached_adaptive_pool tiene el método: vacío constructo (const puntero PTR &, const_reference v) pero no entender lo que significa y no puede encontrar ejemplos de usarlo.

Debe seguir a la interfaz de std::allocator, en cuyo caso allocate() le da un trozo adecuado de la memoria sin inicializar y construct() llamadas de colocación nuevos en el puntero dado.

Algo así como:

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

no ha utilizado esas piscinas mí mismo, sin embargo. En C++ 0x, los asignadores deben poder llamar a cualquier constructor, no solo al constructor de copia, por lo que es posible que los asignadores de boost ya lo admitan en cierta medida.

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

Gracias. La primera forma es el tipo de respuesta que esperaba, pero estaba demasiado confundida y cansada como para darme cuenta. La segunda forma 'a.construct (p, 30, true)' no parece ser compatible con este asignador de impulso específico. Es bastante molesto, ya que 'cached_adaptive_pool.construct()' devuelve 'void', tengo que escribir' allocator_t :: puntero obj = allocator.allocate_one(); allocator.construct (obj, Test (30, verdadero)) '? No estoy seguro de qué es peor, usar dos declaraciones para una operación simple o usar una colocación de aspecto un tanto extraño directamente. – porgarmingduod

+0

Puedes hacer que sea una función separada. – UncleBens

1

Supongo que siempre puedo usar colocación nueva sintaxis. La idea es eliminar la referencia del puntero inteligente (en este caso, offset_ptr) devuelto por el asignador, y luego pasar la dirección sin formato a new().

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

¿Es esta la manera idiomática de hacer esto? Hay muchos otros lugares en los que se brinda apoyo explícito para evitar el uso de la ubicación nueva, lo que me hace pensar que no. En cualquier caso, aceptaré esta respuesta si no se proporciona nada mejor en el futuro cercano.

+0

¿Para qué sirve la secuencia '& * ptr'? – UncleBens

+0

Cuando lo probé, el nuevo solo aceptaba un puntero sin formato, no un offset_ptr que devuelve este asignador. – porgarmingduod

Cuestiones relacionadas