2008-10-30 9 views
28

Quiero tener un mapa que tenga un tipo de clave homogéneo pero tipos de datos heterogéneos.¿Cómo se hace un impulso heterogéneo :: mapa?

quiero ser capaz de hacer algo como (pseudo-código):

boost::map<std::string, magic_goes_here> m; 
m.add<int>("a", 2); 
m.add<std::string>("b", "black sheep"); 

int i = m.get<int>("a"); 
int j = m.get<int>("b"); // error! 

pudiera tener un puntero a una clase base como el tipo de datos sino que más bien no.

Nunca antes había usado boost pero he mirado la biblioteca de fusión pero no puedo entender lo que tengo que hacer.

Gracias por su ayuda.

+2

'boost :: variant' –

+0

Si conoce todos los tipos posibles que puede querer rellenar en el mapa, entonces' boost :: variant' funcionará muy bien. Si quieres literalmente cualquier tipo, entonces 'boost :: any' es el camino a seguir. – Kurt

Respuesta

34
#include <map> 
#include <string> 
#include <iostream> 
#include <boost/any.hpp> 

int main() 
{ 
    try 
    { 
     std::map<std::string, boost::any> m; 
     m["a"] = 2; 
     m["b"] = static_cast<char const *>("black sheep"); 

     int i = boost::any_cast<int>(m["a"]); 
     std::cout << "I(" << i << ")\n"; 

     int j = boost::any_cast<int>(m["b"]); // throws exception 
     std::cout << "J(" << j << ")\n"; 
    } 
    catch(...) 
    { 
     std::cout << "Exception\n"; 
    } 

} 
+1

En lugar del cumbersome_cast, puede usar 'std :: decay'. –

+0

no es solo usar std :: map en lugar de impulsar el mapa como inicializado [aquí] (http://www.boost.org/doc/libs/1_35_0/libs/fusion/doc/html/fusion/container/map. html)? – Tab

9

How can I build a <favorite container> of objects of different types?

No se puede, pero se puede fingir bastante bien. En C/C++ todas las matrices son homogéneas (es decir, los elementos son todos del mismo tipo). Sin embargo, con una capa adicional de indirección puede dar la apariencia de un contenedor heterogéneo (un contenedor heterogéneo es un contenedor donde los objetos contenidos son de diferentes tipos).

Hay dos cajas con contenedores heterogéneos.

El primer caso se produce cuando todos los objetos que desea almacenar en un contenedor se derivan públicamente de una clase base común. [...]

El segundo caso ocurre cuando los tipos de objetos son disjuntos: no comparten una clase base común.
El enfoque aquí es usar una clase de control. El contenedor es un contenedor de objetos de manejo (por valor o por puntero, su elección; por valor es más fácil). Cada objeto de control sabe cómo "aferrarse" (es decir, mantener un puntero) a uno de los objetos que desea colocar en el contenedor. Puede utilizar una clase de identificador único con varios tipos diferentes de punteros como datos de instancia, o una jerarquía de clases de identificador que sombree los diversos tipos que desea contener (requiere que el contenedor sea de identificadores de clase base de manipulador). La desventaja de este enfoque es que abre la (s) clase (s) de manejo al mantenimiento cada vez que cambia el conjunto de tipos que pueden contenerse. El beneficio es que puede usar la (s) clase (s) de manejador para encapsular la mayor parte de la fealdad de la administración de la memoria y la duración del objeto. Por lo tanto, usar objetos de asa puede ser beneficioso incluso en el primer caso.

5

Gracias David, eso era lo que necesitaba. Aquí está la solución de trabajo.

#include <iostream> 
using std::cout; 
using std::endl; 

#include <map> 
#include <boost/any.hpp> 

using boost::any_cast; 
typedef std::map<std::string, boost::any> t_map; 


int main(int argc, char **argv) 
{ 

    t_map map; 
    char *pc = "boo yeah!"; 

    map["a"] = 2.1; 
    map["b"] = pc; 

    cout << "map contents" << endl; 
    cout << any_cast<double>(map["a"]) << endl; 
    cout << any_cast<char*>(map["b"]) << endl; 

    return 0; 
} 
+1

esto debería ser 'const char * pc =" boo yeah! ";' –

0

impulso cualquier duda funciona, pero creo que el uso de Int para escribir La tecnología como el tipo de clave de mapa de fusión es una solución mejor. Sin borrado de tipo y posiblemente más rápido

Cuestiones relacionadas