当我应该使用std :: map :: at来检索map元素

T M*_*T M 46 c++ stdmap c++11

我已经在stackoverflow上阅读了关于web和问题的不同文章,但对我来说,目前尚不清楚是否有更好的std::map::at用于检索map元素的情况.

根据定义,std::map::at

返回对使用键k标识的元素的映射值的引用.

如果k与容器中任何元素的键不匹配,则该函数抛出out_of_range异常.

仅限于我std::map::at在100%确定存在具有特定键的元素时值得使用的情况,否则您应该考虑异常处理.

  1. 有没有哪种情况std::map::at被认为是最有效和优雅的方式?在什么情况下你会建议使用std::map::at
  2. 我是对的,map::find()当有可能没有带有这样一个键的元素时,最好使用它吗?并且map::find()它更快,更好的方法?
if ( map.find("key") != map.end() )
{
    // found 

} else
{
    // not found
}
Run Code Online (Sandbox Code Playgroud)

PS

map::operator[] 有时可能很危险,因为如果一个元素不存在,那么它会插入它.

编辑:链接以某种方式相关链接1 链接2 链接3 链接4 链接5 链接6

Mat*_* M. 64

与此处的大多数现有答案相反,请注意实际上有4种与在地图中查找元素相关的方法(忽略lower_bound,upper_bound并且equal_range不太精确):

  • operator[] 仅存在于非const版本中,如上所述,如果元素不存在,它将创建该元素
  • at()在C++ 11中引入,如果元素存在则返回对该元素的引用,否则抛出异常
  • find()如果元素存在,map::end()则返回元素的迭代器; 如果元素不存在,则返回迭代器
  • count()返回此类元素的数量,在a中map,这是0或1

既然语义很清楚,那么让我们来看看何时使用哪个:

  • 如果您只想知道元素是否存在于map(或不存在),则使用count().
  • 如果你想访问该元素,它应该在map,然后使用at().
  • 如果你想访问该元素,并且不知道它是否在map,那么使用find(); 不要忘记检查生成的迭代器是否不等于结果end().
  • 最后,如果您希望访问该元素(如果它存在)或创建它(并访问它),如果它不存在,请使用operator[]; 如果您不希望调用类型默认构造函数来创建它,那么使用insertemplace适当地使用

  • @Anirudh:两者都不好。第一个(find+[])进行两次查找,第二个使用异常作为控制流。在这种情况下你应该只使用“find”:“if (auto it = map.find(key); it != map.end()) { x = it->second; }` (3认同)

ale*_*in0 21

std::map::at()out_of_range如果找不到该元素,则抛出异常.这个例外是一种logic_error例外,对我来说,它是一种assert()从使用角度来看的同义词:它应该用于报告程序内部逻辑中的错误,比如违反逻辑前置条件或类不变量.

此外,您可以使用at()访问const映射.

所以,对于你的问题:

  1. 我建议使用at()而不是[]在访问const映射时以及元素缺失是逻辑错误时.
  2. 是的,map::find()当你不确定元素在这里时最好使用:在这种情况下,它不是逻辑错误,所以std::logic_error即使我们不考虑性能,抛出和捕获异常也不是非常优雅的编程方式.


Arn*_*rtz 12

正如你提到的,有三种不同的方式来访问一个地图元素:at(),operator[]find()(也有upper_bound,lower_boundequal_range,但这些都是更复杂的情况下,您可能希望找到下一个/上一个元素等)

那么,你什么时候应该使用哪一个?

operator[]基本上是"如果它不存在,用默认构造的映射元素创建一个".这意味着它不会抛出(除非在内存分配抛出或其中一个键或值构造函数抛出的角落情况下),并且您肯定会获得对您查找的元素的引用 - 现有元素或新创建的元素.

at()如果该键没有元素则抛出.由于您不应该使用例外来进行正常的程序流程,因此使用at()"我确信存在这样的元素".但如果你错了,你会得到一个例外(而不是未定义的行为)的额外好处.如果您不确定该元素是否存在,请不要使用此方法.

find()他说:"可能有也可能没有这样的元素,让我们看看..."并为您提供以不同方式对两种情况作出反应的可能性.因此,它是更通用的方法.

  • 很好的答案; 我只是想澄清断言的含义_"我确信有这样一个元素."_ - 通过使用`at()`这样,如果您的代码中存在错误,则会收到异常通知***.因此`at()`是一种不会无意中隐藏错误的好方法. (2认同)

Bar*_*icz 5

所有3 find,operator[]at是有用的.

  • find 如果你不想意外地插入元素,那么这是好的,但只要它们存在就行动.

  • at如果你期望某些东西应该放在地图上并且如果它不是那么你会抛出异常,那就好了.它也可以constfind(你不能使用的地方op[])更简洁的方式访问地图

  • op[]如果你插入一个默认元素,这是很好的,例如为单词计数程序,它0为第一次遇到的每个单词(使用成语words[word]++;)放置一个int .


归档时间:

查看次数:

20067 次

最近记录:

7 年,1 月 前