您的位置:首页 > 其它

关于std::map中的find和[]的问题

2013-03-22 09:11 591 查看
/article/8561704.html

std::map不是顺序容器,这应该都知道的,map中重载了operator []操作符,可以用map的键值索引到相关的数据,但是这个[]和一般数组的[]可不一样。有的人又认为既然[]就是利用下标做索引和std::map中的find用键值索引是不是一样的,所以有的会写出下面类似的代码:

std::map<int,int*> mapTemp;

...

int* Find1(int i)

{

if( mapTemp.end() == mapTemp.find(i) )

return NULL;

return mapTemp[i].second;

}

上面代码有什么问题,看看operator []的源码

mapped_type& operator[](const key_type& _Keyval)

{ // find element matching _Keyval or insert with default mapped

iterator _Where = this->lower_bound(_Keyval);

if (_Where == this->end()

|| this->comp(_Keyval, this->_Key(_Where._Mynode())))

_Where = this->insert(_Where,

value_type(_Keyval, mapped_type()));

return ((*_Where).second);

}

再看看find的源码

const_iterator find(const key_type& _Keyval) const

{ // find an element in nonmutable sequence that matches _Keyval

const_iterator _Where = lower_bound(_Keyval);

return (_Where == end()

|| _DEBUG_LT_PRED(this->comp,

_Keyval, _Key(_Where._Mynode()))

? end() : _Where);

}

对比上面黑色加粗的部分应该知道了吧,就是Find1中你重复找了两遍,标准的写法应该是

int* Find2(int i)

{

std::map<int,int*>::iterator iter = mapTemp.find(i);

if( mapTemp.end() != iter )

return iter->second;

return NULL;

}

其实Find1还好,就是多查了一遍,至少还判了索引的有效值,如果写成下面这样

int* Find3(int i)

{

return mapTemp[i].second;

}

那就悲剧了,再看看operator []的源码红色加粗的部分,[]操作符再没有找到该键值索引值的时候会插入一个键值索引为i的东西,这东西要是不了解bug查起来肯定会比较头痛的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: