如何在 C++ 中创建哈希值的哈希值?

发布于 2024-12-26 03:42:40 字数 898 浏览 1 评论 0原文

有没有办法在 C++ 中创建哈希值的哈希值?

实际上,我正在尝试做你可以在 Perl 中做的事情,但只能在 C++ 中做。 这是我希望在 C++ 中发生的 Perl 代码示例。

%hash = (
gameobject1 => {
    position => {
        x_loc => 43,
        y_loc => 59,
    }
    rect_size => {
        width => 5,
        height => 3,
    }
    collidable => 1,
    sounds => {
        attack => "player_attack.ogg",
        jump => "player_jump1.ogg",
        jump_random => [qw/player_jump1.ogg player_jump2.ogg player_jump3.ogg/]
    }

},
gameobject2 => {
    position => {
        x_loc => 24,
        y_loc => 72,
    }
    rect_size => {
        width => 2,
        height => 4,
    }
    sounds => {
        attack => "goblin_attack.ogg",
    }
        items => [qw/sword helmet boots/]
},
);

要注意的是游戏对象中的哈希值可以存在或不存在...即位置可能存在于游戏对象 1 中,但可能不存在于游戏对象 35 中。

有什么想法吗?

Is there a way to create a hash of hashes in C++?

Effectively I am trying to do what you can do in Perl but only in C++.
Here is an example of Perl code I would like to have happen in C++

%hash = (
gameobject1 => {
    position => {
        x_loc => 43,
        y_loc => 59,
    }
    rect_size => {
        width => 5,
        height => 3,
    }
    collidable => 1,
    sounds => {
        attack => "player_attack.ogg",
        jump => "player_jump1.ogg",
        jump_random => [qw/player_jump1.ogg player_jump2.ogg player_jump3.ogg/]
    }

},
gameobject2 => {
    position => {
        x_loc => 24,
        y_loc => 72,
    }
    rect_size => {
        width => 2,
        height => 4,
    }
    sounds => {
        attack => "goblin_attack.ogg",
    }
        items => [qw/sword helmet boots/]
},
);

The thing to note is the hashes with in gameobjects can exist or not... i.e. position might exist in gameobject1 but may not exist for gameobject35.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

软的没边 2025-01-02 03:42:40

Perl 哈希允许您使用任何值。 C++ 是一种静态类型语言,它不允许您这样做:您必须准确指定您希望散列(在 C++ 术语中,即映射)中的值具有的类型。

这是使用 C++11 和 boost 的可能解决方案,其中包含一些强类型:)

#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" }
    } }
};

如果您确实想要像 Perl 散列的 Perl 散列之类的东西,您可以使用 std::map获得在地图中存储任何内容的能力。但是,这要求您在从映射获取每个值之前测试其类型。如果只能使用一组特定类型,则可以使用比 boost::any 更强类型的内容,例如 boost::variant

Perl hashes let you use anything for values. C++ being a statically typed language, it won't let you do that: you have to specify exactly what type you want the values in the hash (in C++ lingo, the map) to have.

Here's possible solution with C++11 and boost, with some strong typing thrown in :)

#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" }
    } }
};

If you really want something like a Perl hash of Perl hashes, you can use std::map<std::string, boost::any> to get the ability to store anything in the map. However, this requires you to test for the types of every value before obtaining it from the map. If only a certain set of types is possible, you can use something more strongly-typed than boost::any, like boost::variant.

So尛奶瓶 2025-01-02 03:42:40

使用 std::map 吗?

像这样的东西:

#include <map>
#include <string>
class GameObject;
typedef std::map<std::string, GameObject> object_map_t;
typedef std::map<std::string, object_map_t> map_of_object_maps_t;

Use std::map?

Something like:

#include <map>
#include <string>
class GameObject;
typedef std::map<std::string, GameObject> object_map_t;
typedef std::map<std::string, object_map_t> map_of_object_maps_t;
冷心人i 2025-01-02 03:42:40

这个例子可以帮助您理解实现:

#include <map>
#include <string>
#include <iostream>
using namespace std;

void main() {

    map<string, map<string, int>> hash;
    hash["A"]["A"] = 1;
    hash["A"]["B"] = 2;
    hash["B"]["A"] = 4;
    hash["B"]["B"] = 8;

    for(map<string, int>::iterator i = hash["B"].begin(); i != hash["B+"].end(); i++) {
        cout << i->first << " - " << i->second << "\n";
    }
}

干杯...:)

This example can help you to understand the implementation:

#include <map>
#include <string>
#include <iostream>
using namespace std;

void main() {

    map<string, map<string, int>> hash;
    hash["A"]["A"] = 1;
    hash["A"]["B"] = 2;
    hash["B"]["A"] = 4;
    hash["B"]["B"] = 8;

    for(map<string, int>::iterator i = hash["B"].begin(); i != hash["B+"].end(); i++) {
        cout << i->first << " - " << i->second << "\n";
    }
}

Cheers...:)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文