Я думаю, что ваше решение довольно хорошее: оно понятно, и, за исключением случаев, когда вы можете «угадать» хеш-значения на основе условия, я не думаю, что вы могли бы быть намного более производительным. Однако вы можете изменить свою функцию, чтобы сделать ее более общей:
template<typename TKey, typename TValue, typename Predicate>
void filter (const map<TKey, TValue> & m,
set<TKey> & result,
Predicate & p)
{
typename map<TKey,TValue>::const_iterator it = m.begin();
typename map<TKey,TValue>::const_iterator end = m.end();
for( ; it != end ; ++it)
{
TKey key = it->first;
if (p(key))
result.insert(key);
}
}
Ваш пример может быть написан с использованием функтора в качестве предиката:
struct Contains {
Contains(const string & substr) : substr_(substr) {}
bool operator()(const string & s)
{
return s.find(substr_) != string::npos;
}
string substr_;
};
Тогда вызов фильтра будет выглядеть так:
map<string, Obj> m;
// Insert in m
set<string> res;
filter(m, res, Contains("stringToFind"));