¿Cómo se hace un impulso heterogéneo :: mapa?

Quiero tener un mapa que tenga un tipo de clave homogéneo pero tipos de datos heterogéneos.

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

boost::map m; m.add("a", 2); m.add("b", "black sheep"); int i = m.get("a"); int j = m.get("b"); // error! 

Podría tener un puntero a una clase base como tipo de datos, pero preferiría no hacerlo.

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 tu ayuda.

 #include  #include  #include  #include  int main() { try { std::map m; m["a"] = 2; m["b"] = static_cast("black sheep"); int i = boost::any_cast(m["a"]); std::cout << "I(" << i << ")\n"; int j = boost::any_cast(m["b"]); // throws exception std::cout << "J(" << j << ")\n"; } catch(...) { std::cout << "Exception\n"; } } 

¿Cómo puedo crear un de objetos de diferentes tipos?

No puedes, pero puedes fingir bastante bien. En C / C ++ todas las matrices son homogéneas (es decir, todos los elementos son 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 casos con contenedores heterogéneos.

El primer caso ocurre 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 objeto 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 manipulador 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.

Impulsaría: ¿hay alguien que haga el truco para ti?

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

 #include  using std::cout; using std::endl; #include  #include  using boost::any_cast; typedef std::map 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(map["a"]) << endl; cout << any_cast(map["b"]) << endl; return 0; } 

Si desea que se admita un conjunto limitado de tipos, Boost.Variant debería hacer el truco.

impulsar seguramente funciona, pero creo que usar Int para escribir Tecnología como el tipo clave de mapa de fusión es una mejor solución. Sin borrado de tipo y posiblemente más rápido