std :: map准备但不插入

时间:2011-11-17 10:03:12

标签: c++ stl map

我有一个std:map定义如下:

std:map<std::string country, std::vector<SomeClass> events>; 

举行一些将在世界上某些国家发生的事件。

我希望我的main函数在给定键的名称但不插入值的情况下创建此映射。 假设关键是一个国家的名称。我想创建“位置”“美国”而不插入将来会发生的事件。

我的event()函数将在不检查密钥是否有效的情况下输入新的

这可能吗?不知何故以“空”值输入value_pair?

更新:没有提升......

4 个答案:

答案 0 :(得分:4)

插入一个空vector会不会这样做?...

events.insert(std::make_pair("USA", std::vector<SomeClass>()));

然后,您可以在不检查地图值的存在的情况下添加实际事件:

void event(const std::string& country, const SomeClass& data) {
    events[country].push_back(data);
}

我不确定这是否是您正在寻找的,因为“创造”位置“美国”的概念看起来很模糊。 (早期的答案似乎对它有不同的解释)。

编辑:正如评论者指出的那样,甚至不需要插入空矢量,因为地图值是自动创建的(使用默认初始值设定项)&amp;当使用[]运算符时插入。因此,您可以直接执行events["USA"].push_back(data)

答案 1 :(得分:2)

我认为你要找的是std::multimap。这允许每个键有多个值:

typedef std::multimap<std::string, SomeClass> EventMap;
typedef EventMap::value_type EntryType; // std::pair<..>

std::multimap<std::string, SomeClass> events;
// Add value
events.insert(std::make_pair("Norway", SomeClass(...)));

如果您确实需要通过插入空占位符来标记国家/地区是有效的,我认为使用单独的std::set可能是更好的解决方案。如果你真的想这样做,那么sehe提到的boost::optionalshared_ptr是另一种解决方案。

答案 2 :(得分:2)

你的问题有点不清楚。如果不插入值,也无法插入密钥。如果这确实是你的意图,答案是:否。

为了您的目的,我认为没有理由不能插入空载体(正如其他人指出的那样)。实际上,您可以在初始化地图时插入:

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

class SomeClass { int x; };

int main() {
  SomeClass e1, e2, e3;
  map< string, vector<SomeClass> > events = // using initializer_list from c++0x  
  {
    {"USA",{e1,e2}}, {"CANADA",{ /* no events */ }, {"MEXICO",{e2,e3}}
  };
  // or later ...
  events["CUBA"] = {};
  events["RUSSIA"] = {e1,e2,e3};
}

或者,如果在您提出要求时该键不存在,您可以返回默认值,即lazy initializationmap的默认行为是,只要缺少请求的密钥,就使用值类型的默认构造函数向地图添加新条目。在这种情况下,这会产生一个空的vector<SomeClass>。 因此,我不明白这有什么问题:

events["key that is missing beforehand"].push_back(e1);

如果您确实想避免向地图添加新条目,则需要使用以下内容包装您的请求:

string key = "USA";
vector<SomeClass> localEvents; // default, empty vector
// using the auto type from c++0x
auto ev = events.find(key);
if (ev == events.end()) // not found
  //events[key] = {}; // don't add the key to the map
  ;
else // get the corresponding vector
  localEvents = (*ev).second;

为此,您可能还需要考虑以下相关问题:std::map default value

(即使没有c++0x功能,这些示例也能完美运行。)

答案 3 :(得分:1)

惯用解决方案

typedef std::shared_ptr<SomeClass> element_t;
std::map<std::string, std::vector<element_t> >; 

或者

typedef boost::optional<SomeClass> element_t;
std::map<std::string, std::vector<element_t> > map; 

然后你可以得到它并像这样使用它:

if (map["USA"])
{
     SomeClass& use = *map["USA"];
     // ...
}