2010-11-05 5 views
5

Necesito crear un asignador personalizado para std :: objects (particularmente e inicialmente para std :: vector) pero eventualmente podría usar otroslo peor que puede pasar si no obedezco el dogma de asignadores personalizados sin estado?

La razón por la que necesito crear un asignador personalizado es que necesito rastrear los recursos asignados (pila &) por componentes individuales de la aplicación (esta es una característica inherente de la aplicación). Yo necesito el asignador personalizado para controlar la parte del montón de los recursos, por lo que es esencial que soy capaz de pasar a la std :: vector de algo como constructor de

trackerId idToTrackUsage; 
myAlloca<int> allocator(idToTrackUsage); 
vector<int> Foo(allocator); 

Sin embargo, después de leer un poco he encontrado esta pequeña bomba sobre el estándar STL/C++ (ver referencias) que dice que todas las instancias de asignador de un tipo dado deben ser equivalentes (es decir que == debe volver verdadero para dos instancias) y, la mayoría de las terminales; cualquier asignador debería ser capaz de desasignar la memoria asignada por cualquier otra instancia (es decir, sin tener una manera de saber cuál podría ser esa otra instancia). En resumen, los asignadores no pueden tener estado.

Así que estoy tratando de encontrar la mejor manera de evitar esto. ¿Alguna idea ingeniosa? Realmente, REALMENTE, no quiero tener que mantener una versión personalizada de std :: vector.

EDIT: leo sobre asignadores de ámbito para C++ 0x en http://www2.research.att.com/~bs/C++0xFAQ.html#scoped-allocator pero no pude entender bien cómo esto se aplica a mi problema. Si alguien piensa C++ 0x alivia este problema, por favor comentar

Referencias:

Allocator C++ article in Wikipedia

Some random further reading courtesy of Google

+1

Por cierto, algo relacionado, pero parece recordar que hubo cambios significativos en el modelo del asignador en C++ 0x. Alguien sabe algo acerca de esto? (¿O solo fue esto antes de que se eliminara Concepts?) – jalf

+1

, leí sobre eso en http://www2.research.att.com/~bs/C++0xFAQ.html#scoped-allocator, pero no pude llegar muy lejos. en la comprensión de cómo esto se aplica a mi problema. (actualizará la publicación con esto) – lurscher

Respuesta

5

Aparte de la respuesta obvia ("si usted viola cualquier requisito, eso es un comportamiento indefinido, buenas noches y gracias por jugar"), me imagino que el peor que probablemente iba a pasar, es que la aplicación vector puede confiar en el requisito de que "todas las instancias de la clase asignador son intercambiables" en la manera obvia:

vector(const Allocator &youralloc = Allocator()) { 
    const Allocator hawhaw; 
    // use hawhaw and ignore youralloc. 
    // They're interchangeable, remember? 
} 

en cuanto a la fuente, la implementación del vector de GCC (que creo que se basa finalmente en la aplicación STL original del SGI) hace una especie de tienda una copia del objeto asignador pasó a ese constructor, por lo que hay alguna esperanza de que esto no suceda.

Yo diría que pruébalo y ve, y documenta lo que has hecho con mucho cuidado, para que cualquiera que intente usar tu código en una implementación que no hayas comprobado, sepa lo que está pasando. Los implementadores son alentados en el estándar para relajar las restricciones sobre los asignadores, por lo que sería un sucio truco para que parezca que están relajados cuando en realidad no lo son. Lo cual no significa que no va a suceder.

Si tiene mucha suerte, hay alguna documentación para la implementación de su contenedor que habla sobre los asignadores.

+0

agregué estado al asignador y me aseguré de que == y! = devuelvan la verificación correcta en función del estado, por lo que si se afirma en algún lugar de la inmensidad del código fuente estándar, debería fallar He probado durante medio mes y parece que no lo afirma o necesita verificarlo, y hasta ahora ha funcionado bien, ** al menos con std :: vector ** – lurscher

+1

@lurscher: Pruébelo con 'list' y' map'. Que toman un parámetro 'Allocator ', pero usan 'Allocator ' debajo. Si funciona con eso, probablemente estés bien. –

3

Usted podría, por supuesto, dejar un puntero a cualquier estado que necesita en cualquier asignado bloques. Por supuesto, esto significa que cualquier estado por bloque debe almacenarse en ese bloque, y las instancias del asignador actuarían más como manejadores que como objetos reales en sí mismos.

+1

esta es una posibilidad interesante – lurscher

1

Hacer que el estado del asignador sea estático sería suficiente, si puede trabajar con eso.Significa que todos los asignadores de ese tipo tipo tendrán que compartir su estado, pero según sus requisitos, eso suena como que podría ser aceptable

+0

no hay diferentes asignadores para diferentes componentes tendrán (usando mi código de ejemplo) diferente trackerId, así que básicamente seré capaz de hacer: componente A, 15% de montón, componente B, 67% de montón, etc. – lurscher

+0

@lurscher: y no puedes hacer eso usando un asignador separado para cada componente? – jalf

+0

@lurcsher si necesita diferentes asignadores, aún puede usar el estado estático pero tiene el asignador una clase de plantilla que tiene un parámetro único, por lo que realmente tiene diferentes tipos y diferentes datos estáticos para todas las instancias. – Motti

1

Para responder a su edición: sí, en C++ 0x o C + +11, los asignadores pueden tener estado.

Cuestiones relacionadas