c++ map取值的find、[]、at方法特性对比

背景

项目中经常需要对std::map进行插入和取值操作,以前经常使用find和[]直接操作,c++11引入了at方法。

本文主要介绍它们的使用方法和不同之处。

find

很直观的查找元素操作,如:

#include <map>
#include <iostream>

using namespace std;

int main()
{
	map<string, int> m;
	m["xiaoming"] = 80;
	m["xiaogang"] = 90;
	m["xiaoqing"] = 100;
	
	auto iter = m.find("xiaoqiang");
	if (iter != m.end())
	{
		// 找到了
		cout << "xiaoqiang's score: " << iter->second << endl;
	}
	else
	{
		// not found
		cout << "not find xiaoqiang's score" << endl; // 应该输出该行
	}
		
	return 0;
}

它的特点:

  • 有就是有,没有就是没有,需要判断find的返回结果,才知道有没有
[]

和数组的取值操作一样,使用中括号,由于使用简单(能少打几下键盘),很多人喜欢直接用。

但如果使用错误,调试bug的时候要多打一万倍的键盘([/捂脸])。

其实上个示例中已经使用了[]操作符,这里再扩展一下:

#include <map>
#include <iostream>

using namespace std;

int main()
{
	map<string, int> m;
	m["xiaoming"] = 80;
	m["xiaogang"] = 90;
	m["xiaoqing"] = 100;
	
	cout << "xiaoqing's score: " << m["xiaoqing"] << endl; // 输出100
	cout << "xiaoqiang's score" <<  m["xiaoqiang"] << endl; // 输出0
	
	return 0;
}

看到了吧,[]操作符的特点:

  • 不管有没有,都是有。因为没有就是0,字符串就是空。反正就是给它是初始值。
  • 对于示例中给map插入值的操作,也是一样,如果原先不存在该key,则插入,如果存在,则覆盖插入。
at

c11引入的at方法,用于取值,但它是进行越界检测,这会损失效率。

如果存在,则返回它的值,如果不存在,则抛出异常。

#include <map>
#include <iostream>

using namespace std;

int main()
{
	try
	{
		map<string, int> m;
		m["xiaoming"] = 80;
		m["xiaogang"] = 90;
		m["xiaoqing"] = 100;
		
		cout << "xiaoqing's score: " << m.at("xiaoqing") << endl; // 输出100
		cout << "xiaoqiang's score" <<  m.at("xiaoqiang") << endl; // 抛出异常:out_of_range exception
	}
	catch(std::exception& e)
	{
		cout << "catch exception: " << e.what() << endl;
	}
	
	return 0;
}

可以看出,at的特点如下:

  • 相比于find,能少敲键盘
  • 相比于[],更安全
  • 性能会有损失
  • 所以常用于待查找的key都应该存在的情况,如果查找的key不存在,则说明程序有问题了
  • 其实,我用at还有一个原因,那就是对于const的map,即使是取值,用[]操作符也是发生编译时错误,用at就没事了
小结

虽然都能达到取值的目的,但用法上的些微差别可能导致使用上的bug,所以一般性的建议如下:

  • 如果纯粹是查找取值,不要用[]操作符,因为它会自动创建不存在的元素
  • 正因为上面的原因,[]仅用于非const的情形下。在const map下使用[]会导致编译期错误
  • 如果不确定待查找的值是否存在,且不存在也是合理的,则使用find,判断返回值是否是end()
  • 如果待查找的值肯定存在,如果不存在就是逻辑上的错误,则使用at,处理out_of_range异常

另外,如果仅是判断元素是否存在,也可以使用count,因为map不存在重复的key,所以它的效率也可以。

它比使用find可以少打好几下键盘呢 [/可爱] !

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值