我们都熟知STL 中模板库的std::map可以按key查找,但是有时候应用中会出现Value 也是唯一的,比如你的Value中保存的是GUID等.
如果想要以key查找,那么find已经足够了,如果想按value查找,那就得研究下find_if函数了。
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,Predicate pred)
{
while (first != last && !pred(*first)) ++first;
return first;
}
简单说就是 返回迭代器中first到last之间第一个使得pred函数返回true的 迭代器指针。
所以得自己实现一个比较函数
一种方式是实现一个类,类内提供一个value_type类型成员变量,实现构造函数,重载operator () --基本上这三个就足够了。如下:
class map_value_finder
{
public:
map_value_finder(QString &cmp_string):m_s_cmp_string(cmp_string){}
bool operator ()(const std::map<int, QString>::value_type &pair)
{
if ( pair.second.compare(m_s_cmp_string) == 0)
return true;
return false;
}
private:
const QString &m_s_cmp_string;
};
这种的好处是 调用find_if时很方便,比如:
std::map<int, QString>::iterator iter = m_mapIndexToFileGuid.end();
iter = std::find_if(m_mapIndexToFileGuid.begin(), m_mapIndexToFileGuid.end(), map_value_finder(task->pFileInfo->fileID));
创建一个map_value_finder的临时对象,直接调用其对象的operator()即可。
或者
单独一个函数,此函数专门用来查找value_type
QString strGlobal = "D";
bool TestFindValue(const std::map<int,QString>::value_type &pair)
{
if(pair.second.compare(strGlobal) == 0)
return true;
return false;
}
调用:
std::map<int, QString>::iterator iter = std::find_if(map_Test.begin(), map_Test.end(), TestFindValue);
直接传入函数地址即可。
这种用法就比较繁琐,使用时需要自己去存储value
个人倾向于第一种,网上很多资源也是提供的第一种。
另:std::map 插入的2种方式比较:
1.insert: map.insert(std::makepair(key,value));
2. map[key]=value;
区别:
第一种方式,遍历map,如果没找到key,则插入,否则不插入。
第二种方式,如果没找到则插入,否则将对应的key项的值赋给value。
你可能觉得,第二种方式多好,找不到就插入,比第一种靠谱多了。第二种方式确实更靠谱,但是比起第一种方式,它的代价会更大,这种靠谱是要花时间的。
尤其在遇到value为对象的情况时,就需要好好考虑了。
因为第二种方式相当于是:系统先默认构造一个对象,然后给它赋值,最后还要销毁它(3部分时间)。如果用想要的value赋给对象,显然比默认构造一个对象再赋值更高效。这就是insert。
当对象内属性很多时就更应该考虑了。
具体insert的返回值,可以再深入了解下,比如插入是否成功
single element (1) pair<iterator,bool> insert (const value_type& val);
The single element versions (1) return a
pair
, with its member
pair::first
set to an iterator pointing to either the newly inserted element or to the element with an equivalent key in the
map
. The
pair::second
element in the
pair
is set to
true
if a new element was inserted or
false
if an equivalent key already existed.
返回值为一个pair,pair构成一个迭代器,一个bool变量,bool变量标识是否插入成功,iterator指向插入成功的map元素。
mymap.insert ( std::pair<char,int>('a',100) );
mymap.insert ( std::pair<char,int>('z',200) );
std::pair<std::map<char,int>::iterator,bool> ret;
ret = mymap.insert ( std::pair<char,int>('z',500) );
if (ret.second==false) {
std::cout << "element 'z' already existed";
std::cout << " with a value of " << ret.first->second << '\n';
}