J'ai besoin d'un type variant qui contient des instances de toute classe définie par l'utilisateur. Donc, j'utilise void *:boost :: variant et void * pointers
typedef boost::variant<void*, int, float, std::string> Tvariant;
J'ai créé une classe wrapper avec une carte:
typedef std::map<std::string, Tvariant> Tvalues;
Exemple d'utilisation:
int x = 123;
attributes.set("int_var", x);
x = attributes.get<int>("int_var");
MyClass* obj = new MyClass();
attributes.set("void*_var", obj);
obj = static_cast<MyClass*>(attributes.get<void*>("void*_var"));
obj = attributes.cast<MyClass*>("void*_var"); // the same
Il y a 2 problèmes avec ce vide * en variante:
- Copier des attributs avec des pointeurs sur dyna La mémoire allouée est dangereuse et sujette aux erreurs.
- L'utilisateur peut static_cast void * vers WrongClass *, pas vers MyClass *. Il compile, mais le résultat est imprévisible.
solutions possibles:
- Utiliser boost :: shared_ptr < void *>.
- Rappelez-vous de typeid pour toutes les valeurs void * (lorsqu'elles sont ajoutées) dans
std::map<void*, typeid> typeid_map
. Lorsque l'utilisateur demande la valeur void *, en la convertissant en TClass *, évaluons une assertion:assert(typeid_from_typeid_map == typeid(TClass*))
.
Questions:
1. Y at-il d'autres solutions pour maintenir les valeurs de toutes les catégories définies par l'utilisateur?
2. Peut-être recommanderez-vous de meilleures solutions pour les problèmes mentionnés et signalez-vous d'autres problèmes?
Oui, mais boost :: any ne fournit pas de vérifications à la compilation et est plus lent que boost :: variant. Est-ce que boost :: any fournit une sécurité de type lors de la conversion de n'importe quelle valeur en classe définie par l'utilisateur? –
@topright Comme vous utilisez déjà Boost, boost :: any semble le chemin à parcourir. – karlphillip
@topright: 'boost :: any' fournit la vérification du type d'exécution, et' any_cast' vous demande de spécifier le type que vous voulez récupérer, par exemple. Myclass * c = any_cast (myMap ["myClassObj"]) ', qui lance' bad_any_cast' si vous avez eu tort sur le type. Puisque vous allez rechercher des valeurs dans une carte, je doute que le surcoût de boost: any soit pertinent pour vous. Boost any est syntaxiquement très propre et très sûr. –