STL structures: "insert if not present" operation? - c++

I'm working on a program right now dealing with some exponential time algorithms. Because of this, a main loop of my program is being run many times, and I'm trying to optimize it as much as possible.
Profiling shows that a large portion of the time is spent in look-up and hash calculation for std::unordered_map.
I'm wondering:
Is there a way to cache the hash value of a key for std::unordered_map, and then provide it as an argument to insert later on?
Is there a way that I can do the following in a single operation: given an key and value {x,y}, check if key x is in the map, if it isn't, insert it and return {x,y}, otherwise return {x,z} for whatever z is already in the map.
I'm doing something like this right now, but it's inefficient, because I have to calculate the hash for the key and check if it's in the map. But if it isn't in the map, I do a completely separate insert operation. In theory, checking if it is present in the map should find where it would go in the map if inserted.
I'm open to trying other data structures, like std::map or something from Boost, if they would reduce the time for this operation.

You could just use the return value of std::unordered_map::insert() to achieve key existence checking + insertion with single hash calculation.
template<typename K, typename V>
std::pair<K, V> myinsert(std::unordered_map<K, V> &map, const std::pair<K, V> &kv)
{
return *(map.insert(kv).first);
}

You can't cache the hash of the key, but if you have an iterator to where it was last time (either from when you originally inserted, or the last time you successfully found the item) you can use the insert( const_iterator hint, value_type&& value ); member which also helpfully returns an iterator to either the newly inserted element or the previously existing element that blocked insertion.

You could just use std::map::emplace().
The insertion only takes place if no other element in the container has a key equivalent to the one being emplaced (keys in a map container are unique).
Example
#include <iostream>
#include <utility>
#include <string>
#include <map>
typedef std::map<std::string, std::string> StringMap;
typedef std::pair<StringMap::iterator, bool> PairKey;
int main()
{
std::map<std::string, std::string> m;
// uses pair's template constructor
m.emplace("a", "aaa");
m.emplace("b", "bbb");
m.emplace("d", "ddd");
PairKey pair = m.emplace("d", "dddddd");
if (pair.second == false)
std::cout<< "d was existed so value didn't change" << std::endl;
std::cout<<"-------MAP_LIST------" << std::endl;
for (const auto &p : m)
std::cout << p.first << " => " << p.second << '\n';
std::cout<<"-------========------" << std::endl;
}
Output:
d was existed so value didn't change
-------MAP_LIST------
a => aaa
b => bbb
d => ddd
-------========------

Related

How can I reverse loop over a map by value?

I need to get the pairs of the map sorted by its values, i wonder if it is posible without an temporal declaration.
I know i can sort it if i make another map with the keys and values swaped, but i am searching for a better solution.
I can't sort the elements afterwards because i only need extract the chars and put them on an array for example.
std::map<char,int> list = {{'A',4},{'V',2},{'N',1},{'J',5},{'G',3}};
for(/* code here */){
std::cout << /* code here */ << std::endl;
}
Desired outout:
J 5
A 4
G 3
V 2
N 1
This cannot be done with std::map.
This template has an optional template argument which allows for a custom sorting, but this sorting can only be done on the map's key:
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare.
This choice has been done as to not impose the map's value to be an orderable type.
As an alternative, you can use type std::vector<std::pair<char, int>> in combination with std::sort.
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<std::pair<char,int>> list = {{'A',4},{'V',2},{'N',1},{'J',5},{'G',3}};
std::sort(begin(list), end(list), [](auto lhs, auto rhs) {
return lhs.second > rhs.second ? true : ( rhs.first > rhs.first );
});
for(auto const& pair : list) {
std::cout << pair.first << ", " << pair.second << '\n';
}
}
J, 5
A, 4
G, 3
V, 2
N, 1
Live demo
The most appropriate solution depends on HOW are you going to use that list. Is it created once and queried once? Then anything will do: you can just sort the output.
However, if this is a "live" list that is constantly updated, and you need to query it frequently, I would suggest to keep another map of values to vector of keys. Then you would be able to get your result instantly. At a cost
of more expensive insertion, of course.

Create hash map with parameters ordered in the way inserted

I want to change the std::map (it's hash function) so when iterated to return pairs in the way they are inserted. I have tried with unordered map, but with no success. So I guess I have to create a hash function that is incrementing and returns bigger value every time. How can I do that? I'm not working with big data, so performance is not a problem.
It sounds like you want an ordered map, a hashmap which allows O(1) lookups but remembers the order of insertion (for iteration order). Luckily, an efficient implementation exists in C++:
https://github.com/Tessil/ordered-map
An example from the README is:
#include <iostream>
#include <tsl/ordered_map.h>
int main()
{
tsl::ordered_map<char, int> map = {{'d', 1}, {'a', 2}, {'g', 3}};
map.insert({'b', 4});
map['h'] = 5;
map['e'] = 6;
map.erase('a');
// {d, 1} {g, 3} {b, 4} {h, 5} {e, 6}
for(const auto& key_value : map) {
std::cout << "{" << key_value.first << ", " << key_value.second << "}" << std::endl;
}
return 0;
}
You may also implement it like Python's ordered map, which uses a linked list to track insertion order. An advantage is more efficient deletions (Tessil's ordered-map has O(n) deletions, while a linked list/map would be average O(1)). Assuming the map would normally store a key/value type of type Key, T, you would store T in the linked list, and store an iterator as the internal unordered_map's value type. You would then wrap the class and any iterators to ensure it acts from the outside like a normal hashmap.
The basic outline would look something like the following (the rest is for you to implement, if O(n) deletions are unacceptable). Lists are used since they do not invalidate iterators when an element is removed, and the map is used to find the correct list iterator for deletions by key. Satisfies all the big O issues, albeit with some overhead.
#include <list>
#include <unordered_map>
template <
typename Key,
typename T,
typename Hash = std::hash<Key>,
typename KeyEqual = std::equal_to<Key>,
typename Allocator = allocator<std::pair<Key, T>>
>
class ordered_map
{
public:
using key_type = Key;
using mapped_type = T;
// ....
private:
using list_type = list<T, typename std::allocator_traits<Allocator>::template rebind_alloc<T>>;
using list_iterator = typename list_type::iterator;
using map_type = std::unordered_map<
Key, list_iterator, Hasah, KeyEqual,
typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<Key, list_iterator>>
>;
list_type list_;
map_type map_;
};
I think it would be better to use:
std::vector<std::pair<key,value> myValues.
For insertion you would use code like this
myValues.emplace_back(std::make_pair<key,value>(someKey, someValue));
Preferably you will do this in a loop. Then when you want to get items in order they were inserted you simply loop on index For example using for-ranged based loop to output elements in order they were insterted:
for(auto & pair : myValues)
{
std::cout << "Key: " << pair.first << " Value: " << pair.second << std::endl;
}
Doing this on unordered_map or regular map container would be bad use case for such container.

Why doesn’t std::map provide key_iterator and value_iterator?

I am working in a C++03 environment, and applying a function to every key of a map is a lot of code:
const std::map<X,Y>::const_iterator end = m_map.end();
for (std::map<X,Y>::const_iterator element = m_map.begin(); element != end; ++element)
{
func( element->first );
}
If a key_iterator existed, the same code could take advantage of std::for_each:
std::for_each( m_map.key_begin(), m_map.key_end(), &func );
So why isn’t it provided? And is there a way to adapt the first pattern to the second one?
Yes, it is a silly shortcoming. But it's easily rectified: you can write your own generic key_iterator class which can be constructed from the map (pair) iterator. I've done it, it's only a few lines of code, and it's then trivial to make value_iterator too.
There is no need for std::map<K, V> to provide iterators for the keys and/or the values: such an iterator can easily be built based on the existing iterator(s). Well, it isn't as easy as it should/could be but it is certainly doable. I know that Boost has a library of iterator adapters.
The real question could be: why doesn't the standard C++ library provide iterator adapters to project iterators? The short answer is in my opinion: because, in general, you don't want to modify the iterator to choose the property accessed! You rather want to project or, more general, transform the accessed value but still keep the same notion of position. Formulated different, I think it is necessary to separate the notion of positioning (i.e., advancing iterator and testing whether their position is valid) from accessing properties at a given position. The approach I envision is would look like this:
std::for_each(m_map.key_pm(), m_map.begin(), m_map.end(), &func);
or, if you know the underlying structure obtained from the map's iterator is a std::pair<K const, V> (as is the case for std::map<K, V> but not necessarily for other containers similar to associative containers; e.g., a associative container based on a b-tree would benefit from splitting the key and the value into separate entities):
std::for_each(_1st, m_map.begin(), m_map.end(), &func);
My STL 2.0 page is an [incomplete] write-up with a bit more details on how I think the standard C++ library algorithms should be improved, including the above separation of iterators into positioning (cursors) and property access (property maps).
So why isn’t it provided?
I don't know.
And is there a way to adapt the first pattern to the second one?
Alternatively to making a “key iterator” (cf. my comment and other answers), you can write a small wrapper around func, e.g.:
class FuncOnFirst { // (maybe find a better name)
public:
void operator()(std::map<X,Y>::value_type const& e) const { func(e.first); }
};
then use:
std::for_each( m_map.begin(), m_map.end(), FuncOnFirst() );
Slightly more generic wrapper:
class FuncOnFirst { // (maybe find a better name)
public:
template<typename T, typename U>
void operator()(std::pair<T, U> const& p) const { func(p.first); }
};
There is no need for key_iterator or value_iterator as value_type of a std::map is a std::pair<const X, Y>, and this is what function (or functor) called by for_each() will operate on. There is no performance gain to be had from individual iterators as the pair is aggregated in the underlying node in the binary tree used by the map.
Accessing the key and value through a std::pair is hardly strenuous.
#include <iostream>
#include <map>
typedef std::map<unsigned, unsigned> Map;
void F(const Map::value_type &v)
{
std::cout << "Key: " << v.first << " Value: " << v.second << std::endl;
}
int main(int argc, const char * argv[])
{
Map map;
map.insert(std::make_pair(10, 20));
map.insert(std::make_pair(43, 10));
map.insert(std::make_pair(5, 55));
std::for_each(map.begin(), map.end(), F);
return 0;
}
Which gives the output:
Key: 5 Value: 55
Key: 10 Value: 20
Key: 43 Value: 10
Program ended with exit code: 0

C++ STL map I don't want it to sort!

This is my code
map<string,int> persons;
persons["B"] = 123;
persons["A"] = 321;
for(map<string,int>::iterator i = persons.begin();
i!=persons.end();
++i)
{
cout<< (*i).first << ":"<<(*i).second<<endl;
}
Expected output:
B:123
A:321
But output it gives is:
A:321
B:123
I want it to maintain the order in which keys and values were inserted in the map<string,int>.
Is it possible? Or should I use some other STL data structure? Which one?
There is no standard container that does directly what you want. The obvious container to use if you want to maintain insertion order is a vector. If you also need look up by string, use a vector AND a map. The map would in general be of string to vector index, but as your data is already integers you might just want to duplicate it, depending on your use case.
Like Matthieu has said in another answer, the Boost.MultiIndex library seems the right choice for what you want. However, this library can be a little tough to use at the beginning especially if you don't have a lot of experience with C++. Here is how you would use the library to solve the exact problem in the code of your question:
struct person {
std::string name;
int id;
person(std::string const & name, int id)
: name(name), id(id) {
}
};
int main() {
using namespace::boost::multi_index;
using namespace std;
// define a multi_index_container with a list-like index and an ordered index
typedef multi_index_container<
person, // The type of the elements stored
indexed_by< // The indices that our container will support
sequenced<>, // list-like index
ordered_unique<member<person, string,
&person::name> > // map-like index (sorted by name)
>
> person_container;
// Create our container and add some people
person_container persons;
persons.push_back(person("B", 123));
persons.push_back(person("C", 224));
persons.push_back(person("A", 321));
// Typedefs for the sequence index and the ordered index
enum { Seq, Ord };
typedef person_container::nth_index<Seq>::type persons_seq_index;
typedef person_container::nth_index<Ord>::type persons_ord_index;
// Let's test the sequence index
persons_seq_index & seq_index = persons.get<Seq>();
for(persons_seq_index::iterator it = seq_index.begin(),
e = seq_index.end(); it != e; ++it)
cout << it->name << ":"<< it->id << endl;
cout << "\n";
// And now the ordered index
persons_ord_index & ord_index = persons.get<Ord>();
for(persons_ord_index::iterator it = ord_index.begin(),
e = ord_index.end(); it != e; ++it)
cout << it->name << ":"<< it->id << endl;
cout << "\n";
// Thanks to the ordered index we have fast lookup by name:
std::cout << "The id of B is: " << ord_index.find("B")->id << "\n";
}
Which produces the following output:
B:123
C:224
A:321
A:321
B:123
C:224
The id of B is: 123
Map is definitely not right for you:
"Internally, the elements in the map are sorted from lower to higher key value following a specific strict weak ordering criterion set on construction."
Quote taken from here.
Unfortunately there is no unordered associative container in the STL, so either you use a nonassociative one like vector, or write your own :-(
I had the same problem every once in a while and here is my solution: https://github.com/nlohmann/fifo_map. It's a header-only C++11 solution and can be used as drop-in replacement for a std::map.
For your example, it can be used as follows:
#include "fifo_map.hpp"
#include <string>
#include <iostream>
using nlohmann::fifo_map;
int main()
{
fifo_map<std::string,int> persons;
persons["B"] = 123;
persons["A"] = 321;
for(fifo_map<std::string,int>::iterator i = persons.begin();
i!=persons.end();
++i)
{
std::cout<< (*i).first << ":"<<(*i).second << std::endl;
}
}
The output is then
B:123
A:321
Besides Neil's recommendation of a combined vector+map if you need both to keep the insertion order and the ability to search by key, you can also consider using boost multi index libraries, that provide for containers addressable in more than one way.
maps and sets are meant to impose a strict weak ordering upon the data. Strick weak ordering maintains that no entries are equavalent (different to being equal).
You need to provide a functor that the map/set may use to perform a<b. With this functor the map/set sorts its items (in the STL from GCC it uses a red-black tree). It determines weather two items are equavalent if !a<b && !b<a -- the equavelence test.
The functor looks like follows:
template <class T>
struct less : binary_function<T,T,bool> {
bool operator() (const T& a, const T& b) const {
return a < b;
}
};
If you can provide a function that tells the STL how to order things then the map and set can do what you want. For example
template<typename T>
struct ItemHolder
{
int insertCount;
T item;
};
You can then easily write a functor to order by insertCount. If your implementation uses red-black trees your underlying data will remain balanced -- however you will get a lot of re-balancing since your data will be generated based on incremental ordering (vs. Random) -- and in this case a list with push_back would be better. However you cannot access data by key as fast as you would with a map/set.
If you want to sort by string -- provide the functor to search by string, using the insertCount you could potentiall work backwards. If you want to search by both you can have two maps.
map<insertcount, string> x; // auxhilary key
map<string, item> y; //primary key
I use this strategy often -- however I have never placed it in code that is run often. I'm considering boost::bimap.
Well, there is no STL container which actually does what you wish, but there are possibilities.
1. STL
By default, use a vector. Here it would mean:
struct Entry { std::string name; int it; };
typedef std::vector<Entry> container_type;
If you wish to search by string, you always have the find algorithm at your disposal.
class ByName: std::unary_function<Entry,bool>
{
public:
ByName(const std::string& name): m_name(name) {}
bool operator()(const Entry& entry) const { return entry.name == m_name; }
private:
std::string m_name;
};
// Use like this:
container_type myContainer;
container_type::iterator it =
std::find(myContainer.begin(), myContainer.end(), ByName("A"));
2. Boost.MultiIndex
This seems way overkill, but you can always check it out here.
It allows you to create ONE storage container, accessible via various indexes of various styles, all maintained for you (almost) magically.
Rather than using one container (std::map) to reference a storage container (std::vector) with all the synchro issues it causes... you're better off using Boost.
For preserving all the time complexity constrains you need map + list:
struct Entry
{
string key;
int val;
};
typedef list<Entry> MyList;
typedef MyList::iterator Iter;
typedef map<string, Iter> MyMap;
MyList l;
MyMap m;
int find(string key)
{
Iter it = m[key]; // O(log n)
Entry e = *it;
return e.val;
}
void put(string key, int val)
{
Entry e;
e.key = key;
e.val = val;
Iter it = l.insert(l.end(), e); // O(1)
m[key] = it; // O(log n)
}
void erase(string key)
{
Iter it = m[key]; // O(log n)
l.erase(it); // O(1)
m.erase(key); // O(log n)
}
void printAll()
{
for (Iter it = l.begin(); it != l.end(); it++)
{
cout<< it->key << ":"<< it->val << endl;
}
}
Enjoy
You could use a vector of pairs, it is almost the same as unsorted map container
std::vector<std::pair<T, U> > unsorted_map;
Use a vector. It gives you complete control over ordering.
I also think Map is not the way to go. The keys in a Map form a Set; a single key can occur only once. During an insert in the map the map must search for the key, to ensure it does not exist or to update the value of that key. For this it is important (performance wise) that the keys, and thus the entries, have some kind of ordering. As such a Map with insert ordering would be highly inefficient on inserts and retrieving entries.
Another problem would be if you use the same key twice; should the first or the last entry be preserved, and should it update the insert order or not?
Therefore I suggest you go with Neils suggestion, a vector for insert-time ordering and a Map for key-based searching.
Yes, the map container is not for you.
As you asked, you need the following code instead:
struct myClass {
std::string stringValue;
int intValue;
myClass( const std::string& sVal, const int& iVal ):
stringValue( sVal ),
intValue( iVal) {}
};
std::vector<myClass> persons;
persons.push_back( myClass( "B", 123 ));
persons.push_back( myClass( "A", 321 ));
for(std::vector<myClass>::iterator i = persons.begin();
i!=persons.end();
++i)
{
std::cout << (*i).stringValue << ":" << (*i).intValue << std::endl;
}
Here the output is unsorted as expected.
Map is ordered collection (second parametr in template is a order functor), as set. If you want to pop elements in that sequenses as pushd you should use deque or list or vector.
In order to do what they do and be efficient at it, maps use hash tables and sorting. Therefore, you would use a map if you're willing to give up memory of insertion order to gain the convenience and performance of looking up by key.
If you need the insertion order stored, one way would be to create a new type that pairs the value you're storing with the order you're storing it (you would need to write code to keep track of the order). You would then use a map of string to this new type for storage. When you perform a look up using a key, you can also retrieve the insertion order and then sort your values based on insertion order.
One more thing: If you're using a map, be aware of the fact that testing if persons["C"] exists (after you've only inserted A and B) will actually insert a key value pair into your map.
Instead of map you can use the pair function with a vector!
ex:
vector<::pair<unsigned,string>> myvec;
myvec.push_back(::pair<unsigned,string>(1,"a"));
myvec.push_back(::pair<unsigned,string>(5,"b"));
myvec.push_back(::pair<unsigned,string>(3,"aa"));`
Output:
myvec[0]=(1,"a"); myvec[1]=(5,"b"); myvec[2]=(3,"aa");
or another ex:
vector<::pair<string,unsigned>> myvec2;
myvec2.push_back(::pair<string,unsigned>("aa",1));
myvec2.push_back(::pair<string,unsigned>("a",3));
myvec2.push_back(::pair<string,unsigned>("ab",2));
Output: myvec2[0]=("aa",1); myvec2[1]=("a",3); myvec2[2]=("ab",2);
Hope this can help someone else in the future who was looking for non sorted maps like me!
struct Compare : public binary_function<int,int,bool> {
bool operator() (int a, int b) {return true;}
};
Use this to get all the elements of a map in the reverse order in which you entered (i.e.: the first entered element will be the last and the last entered element will be the first). Not as good as the same order but it might serve your purpose with a little inconvenience.
Use a Map along with a vector of iterators as you insert in Map. (Map iterators are guaranteed not to be invalidated)
In the code below I am using Set
set<string> myset;
vector<set<string>::iterator> vec;
void printNonDuplicates(){
vector<set<string>::iterator>::iterator vecIter;
for(vecIter = vec.begin();vecIter!=vec.end();vecIter++){
cout<<(*vecIter)->c_str()<<endl;
}
}
void insertSet(string str){
pair<set<string>::iterator,bool> ret;
ret = myset.insert(str);
if(ret.second)
vec.push_back(ret.first);
}
If you don't want to use boost::multi_index, I have put a proof of concept class template up for review here:
https://codereview.stackexchange.com/questions/233157/wrapper-class-template-for-stdmap-stdlist-to-provide-a-sequencedmap-which
using std::map<KT,VT> and std::list<OT*> which uses pointers to maintain the order.
It will take O(n) linear time for the delete because it needs to search the whole list for the right pointer. To avoid that would need another cross reference in the map.
I'd vote for typedef std::vector< std::pair< std::string, int > > UnsortedMap;
Assignment looks a bit different, but your loop remains exactly as it is now.
There is std::unordered_map that you can check out. From first view, it looks like it might solve your problem.

Checking value exist in a std::map - C++

I know find method finds the supplied key in std::map and return an iterator to the element. Is there anyway to find the value and get an iterator to the element? What I need to do is to check specified value exist in std::map. I have done this by looping all items in the map and comparing. But I wanted to know is there any better approach for this.
Here is what I have wrote
bool ContainsValue(Type_ value)
{
bool found = false;
Map_::iterator it = internalMap.begin(); // internalMap is std::map
while(it != internalMap.end())
{
found = (it->second == value);
if(found)
break;
++it;
}
return found;
}
Edit
How about using another map internally which stores value,key combination. So I can call find on it? Is find() in std::map doing sequential search?
Thanks
You can use boost::multi_index to create a bidirectional map - you can use either value of the pair as a key to do a quick lookup.
If you have access to the excellent boost library then you should be using boost::multi_index to create bidirectional map as Mark says. Unlike a std::map this allows you to look up by either the key or the value.
If you only have the STL to hand the following code will do the trick (templated to work with any kind of map where the mapped_type supports operator==):
#include <map>
#include <string>
#include <algorithm>
#include <iostream>
#include <cassert>
template<class T>
struct map_data_compare : public std::binary_function<typename T::value_type,
typename T::mapped_type,
bool>
{
public:
bool operator() (typename T::value_type &pair,
typename T::mapped_type i) const
{
return pair.second == i;
}
};
int main()
{
typedef std::map<std::string, int> mapType;
mapType map;
map["a"] = 1;
map["b"] = 2;
map["c"] = 3;
map["d"] = 4;
map["e"] = 5;
const int value = 3;
std::map<std::string, int>::iterator it = std::find_if( map.begin(), map.end(), std::bind2nd(map_data_compare<mapType>(), value) );
if ( it != map.end() )
{
assert( value == it->second);
std::cout << "Found index:" << it->first << " for value:" << it->second << std::endl;
}
else
{
std::cout << "Did not find index for value:" << value << std::endl;
}
}
How about using another map internally which stores value,key combination. So I can call find on it?
Yes: maintain two maps, with one map using one type of key and the other using the other.
Is find() in std::map doing sequential search?
No it's a binary search of a sorted tree: its speed is O(log(n)).
Look into boost's bidirectional maps: http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html
It lets both values act like a key.
Otherwise, iteration is the way to go.
What you are requesting is precisely what std::find does (not the member function)
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
No, you have to loop over the std::map and check all values manually. Depending on what you want to do, you could wrap the std::map in a simple class that also caches all of the values that are inserted into the map in something that's easily search-able and doesn't allow duplicates, like a std::set. Don't inherit from the std::map (it doesn't have a virtual destructor!), but wrap it so that you can do something like this:
WrappedMap my_map< std::string, double >;
my_map[ "key" ] = 99.0;
std::set< double > values = my_map.values(); // should give back a set with only 99.0 in it
An alternative to rolling your own would be to use the Boost bidirectional map, which is easily found in the posts below or by Google.
It really depends on what you want to do, how often you want to do it, and how hard it is to roll your own little wrapper class versus installing and using Boost. I love Boost, so that's a good way to go - but there's something nice and complete about making your own wrapper class. You have the advantage of understanding directly the complexity of operations, and you may not need the full reverse mapping of values => keys that's provided by the Boost bidirectional map.
Not a very best option but might be useful in few cases where user is assigning default value like 0 or NULL at initialization.
Ex.
< int , string >
< string , int >
< string , string >
consider < string , string >
mymap["1st"]="first";
mymap["second"]="";
for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
{
if ( it->second =="" )
continue;
}
I am adding this answer, if someone come here and looks for c++11 and above..
//DECLARE A MAP
std::map<int, int> testmap;
//SAMPLE DATA
testmap.insert(std::make_pair(1, 10));
testmap.insert(std::make_pair(2, 20));
testmap.insert(std::make_pair(3, 30));
testmap.insert(std::make_pair(4, 20));
//ELEMENTS WITH VALUE TO BE FOUND
int value = 20;
//RESULTS
std::map<int, int> valuesMatching;
//ONE STEP TO FIND ALL MATCHING MAP ELEMENTS
std::copy_if(testmap.begin(), testmap.end(), std::inserter(valuesMatching, valuesMatching.end()), [value](const auto& v) {return v.second == value; });
Possible that I don't fully understand what you're trying to accomplish. But to simply test whether or not a map contains a value, I believe you can use the std::map's built in find.
bool ContainsValue(Type_ value)
{
return (internalMap.find(value) != internalMap.end());
}