Perl hash vous permettent d'utiliser quoi que ce soit pour les valeurs. C++ étant un langage typé statiquement, il ne vous laissera pas faire cela: vous devez spécifier exactement le type que vous voulez que les valeurs dans le hachage (en C++ jargon, la carte) aient.
est ici solution avec C++ 11 et coup de pouce, avec une forte frappe jeté :)
#include <map>
#include <vector>
#include <string>
#include <boost/optional.hpp>
// Coordinates are always like this, aren't they?
struct coords {
int x_loc;
int y_loc;
};
// Dimensions are always like this, aren't they?
struct dims {
int width;
int height;
};
// Sound maps: each string key maps to a vector of filenames
typedef std::map<std::string, std::vector<std::string>> sound_map;
// Item lists: looks like it's just a collection of strings
typedef std::vector<std::string> item_list;
// Fancy names to improve readability
enum collidability : bool {
collidable = true,
not_collidable = false
};
// A structure to describe a game object
struct game_object {
// An optional position
boost::optional<coords> position;
// An optional rectangle size
boost::optional<dims> rect_size;
// Assuming "false" can mean the same as "no collidable key"
bool collidable;
// Assuming an "empty map" can mean the same as "no map"
sound_map sounds;
// Assuming an "empty vector" can mean the same as "no vector"
item_list items;
// If any of the above assumptions is wrong,
// sprinkle boost::optional liberally :)
};
// Finally, values for our "hash"
std::map<std::string, game_object> hash {
{ "game_object1",
{
coords { 43, 59 },
dims { 5, 3 },
collidable, // remember those fancy names?
sound_map {
{ "attack", { "player_attack.ogg" } },
{ "jump", { "player_attack.ogg" } },
{ "jump_random", { "player_jump1.ogg", "player_jump2.ogg", "player_jump3.ogg" } }
},
item_list {}
} },
{ "game_object2",
{
coords { 24, 72 },
dims { 2, 4 },
not_collidable,
sound_map {
{ "attack", { "goblin_attack.ogg" } }
},
item_list { "sword", "helmet", "boots" }
} },
{ "game_object25",
{
boost::none, // no position
dims { 2, 4 },
not_collidable,
sound_map {
{ "attack", { "goblin_attack.ogg" } }
},
item_list { "sword", "helmet", "boots" }
} }
};
Si vous voulez vraiment quelque chose comme un hachage Perl de Perl HASHES, vous pouvez utiliser std::map<std::string, boost::any>
pour obtenir le possibilité de stocker quoi que ce soit sur la carte. Cependant, cela vous oblige à tester les types de chaque valeur avant de l'obtenir de la carte. Si seulement un certain ensemble de types est possible, vous pouvez utiliser quelque chose de plus fortement typé que boost::any
, comme boost::variant
.
J'ai remplacé "c/C++" dans votre question par "C++", car C et C++ sont des langages différents. Veuillez me corriger si mon hypothèse était fausse et que vous êtes plutôt intéressé par une solution C. –
J'étais un peu pour l'un ou pour l'autre qui a toujours eu du sens :) C++ fonctionne – vternal3