我怎么知道std :: map insert是成功还是失败?

问题描述 投票:5回答:6

我在一个多线程应用程序中有一个映射,将一个名为uuid的类映射到指针。如果插入操作成功失败,我想知道什么。

EG

_mymap.insert(hint, MyMap::value_type(entry.uuid, itemptr));

如果失败会引发异常吗?

c++ linux gcc stl
6个回答
14
投票

事实上,采用提示参数的insert方法不会返回插入是否成功。检查插入是否实际发生的一种方法是在插入之前和之后检查地图的大小。如果它是相同的,则插入失败(即密钥已经存在)。我知道这听起来很难看,但这是我能想到的最有效的方式。事实上,我认为没有令人信服的理由,带有提示的插入不应该返回一对(包括bool),就像常规的非提示插入一样。但是,一旦在旧标准中指定它,就很难改变,因为它是一个突破性的变化,C ++社区大多都不满。

Original (wrong) answer

See this link

...返回一对,其成员pair::first设置为迭代器,指向新插入的元素或指向已在地图中具有相同值的元素。如果插入新元素,则对中的pair::second元素设置为true;如果存在具有相同值的元素,则设置为false。

该链接还包含一个示例

例如:

if(mp.insert(make_pair(key, value)).second == false)
{
   cout << "Insertion failed. Key was present"
}

8
投票
typedef std::map<std::string, int> map;
map m;
std::pair<map::iterator,bool> result = m.insert(std::make_pair("hi", 42));

result.second包含你想要的东西


3
投票

这取决于你失败或成功的意思。

std :: map :: insert在插入新元素或将迭代器返回到现有元素时成功。

如果没有足够的内存来插入新元素并抛出std :: bad_alloc,则std :: map :: insert会失败。


2
投票

是的,它会抛出STL中使用的一个例外,例如当内存不足时。那是在失败的情况下。

或者您是否也有兴趣了解该元素是否已包含在实例中?


1
投票

第一个插入成员函数返回一个对,其bool组件在插入时返回true;如果映射已经包含其键在序列中具有等效值的元素,并且其迭代器组件返回插入新元素的地址,则返回false或元素已经位于的位置。

要访问此成员函数返回的对pr的迭代器组件,请使用pr.first,并取消引用它,使用*(pr.first)。要访问此成员函数返回的对pr的bool组件,请使用pr.second。

第二个插入成员函数(提示版本)返回一个迭代器,该迭代器指向新元素插入到映射中的位置。

资料来源:http://msdn.microsoft.com/en-us/library/81ac0zkz(v=vs.80).aspx


-1
投票

使用提示方法插入一对相同的第一个和第二个,您确定它不在地图中(例如,对于大小的地图,如(size_t)-1)。如果返回的迭代器具有这个不可能的值,则它已被新插入,如果没有在地图中找到它。然后更改返回的迭代器。示例:在映射m((0,1),(2,3),(4,5))中插入对p(2,4)和p(6,5)。

int main (int argc, char* argv []) {
  std::pair<size_t, size_t> tmp [3] = {
    std::pair<size_t, size_t> (0, 1),
    std::pair<size_t, size_t> (2, 3),
    std::pair<size_t, size_t> (4, 5)
  };
  std::map<size_t, size_t> m ((std::pair<size_t, size_t>*) tmp, (std::pair<size_t, size_t>*) &tmp [3]);

  std::cout << "initial map == ";
  std::for_each (m.begin (), m.end (), [] (const std::pair<size_t, size_t>& p) {
    std::cout << p.first << "->" << p.second << "   ";
  });
  std::cout << std::endl;
  std::cout << std::endl;

  {
    //insertion of a pair of first already in map
    std::cout << "insertion of pair 1 == std::pair<size_t, size_t> (2, 4) from second iterator" << std::endl;
    std::map<size_t, size_t>::iterator ihint (m.begin ()), k (ihint); ++ihint;
    std::pair<size_t, size_t> pfoo (2, (size_t) -1);
    k = m.insert (ihint, pfoo);
    if (k->second == (size_t) -1) {
      std::cout << "\tthe pair was inserted" << std::endl;
      k->second = 4;
    }
    else {
      std::cout << "\ta pair with such a first was in the map" << std::endl;
    }
  }
  std::cout << "m after insertion of pair 1 == ";
  std::for_each (m.begin (), m.end (), [] (const std::pair<size_t, size_t>& p) {
    std::cout << p.first << "->" << p.second << "   ";
  });
  std::cout << std::endl;
  std::cout << std::endl;

  {
    //insertion of a pair of first not in map
    std::cout << "insertion of pair 2 == std::pair<size_t, size_t> (6, 5) from third iterator" << std::endl;
    std::map<size_t, size_t>::iterator ihint (m.begin ()), k (ihint); ++ihint; ++ihint;
    std::pair<size_t, size_t> pfoo (6, (size_t) -1);
    k = m.insert (ihint, pfoo);
    if (k->second == (size_t) -1) {
      std::cout << "\tthe pair was inserted" << std::endl;
      k->second = 5;
    }
    else {
      std::cout << "\ta pair with such a first in the map" << std::endl;
    }
  }
  std::cout << "m after insertion of pair 2 == ";
  std::for_each (m.begin (), m.end (), [] (const std::pair<size_t, size_t>& p) {
    std::cout << p.first << "->" << p.second << "   ";
  });
  std::cout << std::endl;
}

输出:初始映射== 0-> 1 2-> 3 4-> 5

从第二个迭代器插入pair 1 == std :: pair(2,4)

这样一个第一对就在地图上

插入对1后的m = = 0-> 1 2-> 3 4-> 5

从第三个迭代器插入对2 == std :: pair(6,5)

这对是插入的

插入对2后的m = = 0-> 1 2-> 3 4-> 5 6-> 5

© www.soinside.com 2019 - 2024. All rights reserved.