【问题标题】:std::map with string key and custom value field带有字符串键和自定义值字段的 std::map
【发布时间】:2015-03-13 08:02:55
【问题描述】:

如何使用string 键和自定义值字段创建std::map

我想要一个std::map,如下所示:

 "Name" "abcd"
 "age"  "50"
 "Address" "Street" "xxxx"
           "PIN"    "xxxx"
           "District" "xxxx"
 "Gender" "Male"

所以我的所有字段除了第三个字段都是string,string 类型。但地址本身就是另一个带有string string 对的地图。

如何在 c++ 中创建这样的地图?

【问题讨论】:

  • 您的值必须是能够表示字符串或从字符串到字符串的映射的类型。
  • 我认为您应该将其建模为一个类而不是一个地图。
  • 您描述的是记录,也就是 struct(或 class),而不是地图。如果你真的需要一张地图,那么你可能应该使用std::map<string, variant>,例如使用来自 Boost 或 Qt 的变体。如果您认为您需要 amap,您可能应该解释原因。最佳解决方案取决于您需要地图的原因。

标签: c++ visual-c++ stdmap


【解决方案1】:

您需要映射类型是可以存储字符串或映射的东西。一种方法是使用Boost.Variant:

typedef boost::variant<std::string, std::map<std::string, std::string>> Value;

typedef std::map<std::string, Value> TheMapYouWouldUse;

阅读我链接的文档以了解如何访问这些值。

另一种方法是提供您自己的受限解决方案。也许是这样的(有点骇人听闻):

class Value
{
  std::map<std::string, std::string> values;

public:
  std::string& asString()
  { return values[""]; }

  std::map<std::string, std::string>& asMap()
  { return value; }
};

界面当然会根据您的实际需求进行调整。

【讨论】:

    【解决方案2】:

    这很容易。 您可以使用带有矢量的地图,其中矢量中的每个索引代表一个项目。

    代码未测试,只是输入

    std::map<std::string, std::vector<std::string>> items;
    items["Address"].push_back("xxxx")
    

    或者你可以使用列表地图

    std::map<std::string, std::list<std::string>> items;
    items["Address"].push_back("xxxx")
    

    或者你可以使用地图地图

    std::map<std::string, std::map<std::string, std::string>> items;
    std::map<std::string, std::string> subItems;
    subItems.insert(std::pair<std::string, std::string>("Street", "xxxx");
    subItems.insert(std::pair<std::string, std::string>("District", "xxxx");
    items["Address"] = subItems;
    

    【讨论】:

    • 感谢您的回答。如果我使用第一种方法,我将值“Street”(它实际上是值“xxxx”的键)。同样在第二种方法(地图地图)我如何添加名称字段。它只有一个值。
    • 选项一意味着 Street 是索引 0,District 是索引 1,依此类推。
    • @user2621310 你意识到你正在重新实现struct 对吗?我的意思是我见过一些固执的人试图重新实现向量或字符串,但是 struct,这是第一次。
    • @Félix Cantournet 当您查看他的示例时,这并不完全是一个结构。但是结构体也可以用来解决他的问题。
    • @user743414 这怎么不是一个结构/类,其中一个成员(地址)是另一个结构或 std::map ?请不要鼓励这样做。您正在重新实现 struct,这同样不太灵活,不太安全,更复杂和更慢。你为什么要这样做?
    【解决方案3】:

    您应该创建一个代表您的人员对象的类,而不是地图。

    enum class Gender
    {
    male,
    female
    };
    
    class ZipCode
    {
    // ...
    };
    
    class Address
    {
      Address(std::string const& s, std::string const& p, std::string const& d):
         street(s),
         pin(p),
         district(d)
      {
      }
    
    private:
      std::string street;
      std::string pin;
      std::string district;  
    };
    
    class Person
    {
    public:
      Person(std::string const& n, Gender d, Address const& a):
        name(n),
        gender(g),
        address(a)
      {
      }
    
      // now add methods operating on the data.
    
    private:
      std::string name;
      Gender gender;
      Address address;
    };
    

    不要创建一个只有 getter 和 setter 的类,而是尝试为方法找到合理的服务。一般尽量避免使用二传手。

    【讨论】:

    • 想解释一下否决票?我认为这是一个设计问题,而不是语言问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-05
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多