Utilizando C++, intento crear una clase de contenedor genérica para manejar múltiples tipos de datos. Es un problema común con una variedad de soluciones, pero no he encontrado nada tan ... intuitivo como me he acostumbrado en lenguajes como Python o incluso VB/VBA ...Contenedor genérico para múltiples tipos de datos en C++
Así que aquí está mi escenario:
He creado una clase DataContainer basada en boost :: cualquiera que utilizo para almacenar múltiples tipos de datos de múltiples elementos. Yo uso un mapa declarado:
std::map<std::string, DataContainer* (or DataContainerBase*)>
donde DataContainer es una clase que encapsula un objeto del tipo:
std::list<boost::any>
junto con funciones de confort para la gestión/acceso a la lista.
Sin embargo, al final, todavía estoy obligado a hacer conversiones de tipo fuera del contenedor de datos.
Por ejemplo, si tuviera que almacenar una lista de valores int en el mapa, para acceder a ellos se requieren:
int value = boost::any_cast<int>(map["myValue"]->get());
prefiero el código impulso estar contenida enteramente dentro de la estructura del contenedor de datos, por lo Sólo necesitaría tipo:
int value = map["myValue"]->get();
o, en el peor de los casos:
int value = map["myValue"]->get<int>();
Por supuesto, yo co ULD enumerar mis tipos de datos y hacer algo como:
int value = map["myValue"]->get(TYPE_INT);
o escribir get-tipo específico() funciones:
getInt(), getString(), getBool() ...
El problema con las dos últimas opciones es que son un poco inflexible, que me exigía declarar explícitamente cada tipo que deseo almacenar en el contenedor. La solución any_cast (que he implementado y funciona) supongo que está bien, es solo ... ¿poco elegante? No se. Parece que no debería necesitar emplear la mecánica interna externamente también.
Como lo veo, pasar el valor sin declarar el tipo de valor en la llamada a la función miembro de DataContainer requeriría una solución void * (que es indeseable por razones obvias), y usar una llamada "get()" requieren (por lo que puedo decir) una función de miembro de "plantilla virtual" definida en el nivel de clase base, que, por supuesto, no está permitida.
Como lo tengo, tengo una solución viable, y realmente, mi uso en este caso es lo suficientemente limitado como para que la mayoría de las soluciones funcionen bien. Pero me pregunto si tal vez haya una manera más flexible de administrar un contenedor de datos genérico de varios tipos que este.
echar un vistazo a 'impulso :: variant' también, tal vez esto es lo que estás buscando (?). – Kos
¿Qué pasa con solo un 'std :: map'? –
Además, dado que su 'DataContainer' está bajo su control, ¿por qué no simplemente agrega una plantilla de función' plantilla get_as() {return boost :: any_cast (get()); } 'para envolver el any-cast? Luego puede decir 'm [" abc "] -> get_as ()', como sugirió. Suena bastante simple. –