【问题标题】:Storing std map in map在地图中存储标准地图
【发布时间】:2010-12-18 16:49:56
【问题描述】:

我必须将 std::map 作为值存储在 std::map 中

std::map< std::string, std::map<std::string, std::string> > someStorage;

如何插入第二个(内部)地图?我试过了:

someStorage.insert( std::make_pair("key", std::make_pair("key2", "value2")) );

但这会引发很多错误。怎么了?

【问题讨论】:

  • 你能edit 比“抛出很多错误”更具体吗?

标签: c++ map insert std


【解决方案1】:

试试:

std::map< std::string, std::map<std::string, std::string> > someStorage;

someStorage["Hi"]["This Is Layer Two"] = "Value";

【讨论】:

  • 这是不必要的昂贵,因为它会创建一个默认字符串,然后将其重新分配给传入的值。最好的方法是 Dark Falcon 是如何做到的:stackoverflow.com/questions/4479017/storing-std-map-in-map/… - 我认为你得到了投票这些天只是因为您累积的积分,而不是您的答案的质量。我希望人们花时间阅读/思考您的答案。
  • 我喜欢我的回答,因为它最容易阅读。费用很少是一个因素,可维护性是一个真正的成本。这段代码是最容易维护的。 PS。此外,复制一个字符串与复制几个整数一样昂贵(因为most std::string 实现使用写时复制方法,因此实际上并未复制字符串)。
  • @Oxsnarder:创建默认字符串然后为其分配char const* 的成本是多少?默认的std::string 可能没有内存分配(如果你有,请关闭你的库提供程序),然后是std::string&amp; std::string::operator=(char const*),当然如果字符串已经存在,那么你避免构建一个临时的std::string 赢得无论如何都不要被插入... 认为你这些天不必要地活泼。
  • 我对这里发生的战斗并不特别感兴趣——但请记住,您上面的答案在语义上并不等同于 insert,因为它会覆盖一个已经存在的值,而insert 不会。当然,哪个更可取取决于上下文 - 但这种情况下的原始问题似乎确实要求insert
  • @Gracchus:C++03 对性能的影响最多可以忽略不计。使用 C++11 和移动语义就更不相关了。您现在需要考虑的是使用std::mapstd::unordered_map 的天气。
【解决方案2】:
someStorage["key"].insert(std::make_pair("key2", "value2")));

如果您还想在外部地图上使用插入,这里有一种方法

std::map<std::string, std::string> inner;
inner.insert(std::make_pair("key2", "value2"));
someStorage.insert(std::make_pair("key", inner));

【讨论】:

  • 您确实意识到 someStorage["key"] 会在需要时使用默认初始化值进行插入? (换句话说,如果键不存在,则与该键关联一个空映射)
  • 你不应该使用 make_pair。您假设实现使用pair。使用std::map&lt;Key, Value&gt;::value_type 正是出于这个原因,它是类型定义的。
  • 相反:C++0x 标准说:“对于 map,key_type 是 Key,value_type 是 pair。” (23.4.1.2)
  • @Martin:他引用的那一点本质上是标准的特定保证,即两者是等价的。换句话说,make_pair 始终可以保证在这里工作(而且就其价值而言,根据我的经验,这是在执行 insert 时的惯用用法)。
  • @Stuart Golodetz:@Dark Falcon:是的。我明白那个。但是你认为 make_pair 返回的类型是什么?作为提示,它与 value_type 不同,因为“key1”、“key2”、“value2”不是 std::strings!您幸运地进行了几次隐式转换。通过使用 value_type,您可以获得正确的类型,而不必担心编译器会进行任何隐式转换。在我的团队中(可能是公司范围内): make_pair 在代码审查时被删除。这里 value_type 是惯用的(因为它是存储在地图中的类型)。
【解决方案3】:

//试试这个:

std::map< std::string, std::map<std::string, std::string> > myMap;

myMap["key one"]["Key Two"] = "Value";
myMap["Hello"]["my name is"] = "Value";

//要打印地图:

for( map<string,map<string,string> >::const_iterator ptr=myMap.begin();ptr!=myMap.end(); ptr++) {
    cout << ptr->first << "\n";
    for( map<string,string>::const_iterator eptr=ptr->second.begin();eptr!=ptr->second.end(); eptr++){
        cout << eptr->first << " " << eptr->second << endl;

    }

}

【讨论】:

    【解决方案4】:

    你也可以使用列表初始化:

    someStorage.insert( std::make_pair("key", std::map<std::string, std::string> {std::make_pair("key2", "value2")}) );
    

    【讨论】:

      【解决方案5】:

      地图有一个插入方法,它接受一个键/值对。您的键是字符串类型,所以没问题,但您的值是 not 类型对(您生成)但类型映射。因此,您要么需要将完整的映射存储为您的值,要么更改初始映射定义以接受一对作为值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-18
        • 1970-01-01
        • 1970-01-01
        • 2020-12-13
        • 2015-11-28
        相关资源
        最近更新 更多