This question already has answers here:
How to use range-based for() loop with std::map?
(5 answers)
Closed 7 years ago.
I know that in order to loop through a map in C++11 I can use the following code:
std::mymap<std::string, myclass>
for(auto item : mymap)
{
// code here
}
What exactly is referred to by item? Is it the map key? The value that is currently accessed? If I want to do something with the value, how do I access it?
Iter refers to a std::pair<std::string, myclass> in your context. So iter.first is your key and iter.second is value for your example.
If you want to modify value inside loop block, you can write as follows:
iter.second=<new value>
If you don't need to modify the value better to use your range loop as follows:
for(const auto& iter : mymap)
{
//
}
Related
This question already has answers here:
How to remove from a map while iterating it?
(6 answers)
Closed 2 years ago.
I use this code to remove elements from map container that equal to some int.
for(auto x:m){
if((x.second)==element)m.erase(x.first);
}
As result Segmentation fault. I also tried this:
for(map<int,int>::iterator i=m.begin();i!=m.end();i++){
if((i->second)==element)m.erase(i);
}
Same result. If you put i++ into if/else program will freeze/loop or something. How can I fix this?
erase() invalidates the iterator being used by the for loop. Fortunately, erase() itself returns an iterator to the next entry, so the correct loop would look like this instead:
for (map<int,int>::iterator i = m.begin(); i != m.end(); )
{
if (i->second == element)
i = m.erase(i);
else
++i;
}
In addition to #john's answer, if your C++ Standard Library implementation supports it, you can invoke the std::erase_if(map, condition) helper:
std::erase_if(m, [](const auto& item) {
auto const& [key, value] = item;
// Write your erasing condition here, e.g.:
// return value == element;
});
This question already has answers here:
Range based loop: get item by value or reference to const?
(5 answers)
Closed 4 years ago.
Suppose a class Object exists.
I now have vector<Object> vec
If I now do in some part of my code:
for(auto p : vec){
//something with p
}
Does this make a new object p for every object that actually in the iterator? Or does it actually just go through the actual objects in the list? I'm asking because I've also seen auto& p
Yes, it will make a copy of each item, to have a reference you should do:
for (auto& p : vec) {}
Also, if you want to protect items from any change, you can have const to reference:
for (const auto& p : vec) {}
The range based for loop you have
for(auto p : vec) /* ... */
copies every element in vec into the loop variable p. Hence, any changes you apply to p does not affect the elements in vec. And yes, if you change the loop to
for (auto& p : vec) /* ... */
then p is a reference to the vec elements, and changes applied to p are changes you apply to the corresponding vec element.
This question already has answers here:
How can I modify values in a map using range based for loop?
(4 answers)
Closed 5 years ago.
pair<bool, char> pos_panlindrome(unordered_map<char, int>& smap){
for(auto m : smap){
m.second /= 2;
}
}
Where I declared smap in another function calling pos_panlindrome. I want all the mapped value (in spite of the key value) to be halved. But somehow, when I print out the smap after pos_panlindrome function, none of the mapped_value got changed.
Why is that case?
The problem is that you're using an unmodified auto in your for loop. This creates a copy of each map element, and then you modify the copy. You need a reference if you want to change the entry in the map. Try this instead:
for (auto& m : smap)
{
m.second /= 2;
}
This question already has answers here:
How can I loop through a C++ map of maps?
(9 answers)
Closed 9 years ago.
So, I have an std::map<int, my_vector> and I want to go through each int and analyse the vector.
I haven't gotten to the part of analyzing the vector just yet, I'm still trying to figure out how to go through every single element on the map.
I know it is possible to have an iterator, but I didn't quite understood how it works, also, I don't know if there isn't a better way to do what I intend to do
You can simply iterate over the map. Each map element is an std::pair<key, mapped_type>, so first gives you the key, second the element.
std::map<int, my_vector> m = ....;
for (std::map<int, my_vector>::const_iterator it = m.begin(); it != m.end(); ++it)
{
//it-->first gives you the key (int)
//it->second gives you the mapped element (vector)
}
// C++11 range based for loop
for (const auto& elem : m)
{
//elem.first gives you the key (int)
//elem.second gives you the mapped element (vector)
}
Iterators are the perfect thing for this. Look around http://www.cplusplus.com/reference/map/map/begin/
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
stl::multimap - how do i get groups of data?
What i want to do is to compute the list of values of every key stored in the multimap.
Use equal_range(); it returns a pair of iterators describing the range of items with the specified key.
A generic answer to the generic question is:
template<class KEY, class VALUE>
std::vector<VALUE> getValues(const std::multimap<KEY,VALUE>& aMap){
std::vector<VALUE> values;
for(multimap<KEY,VALUE>::const_iterator it=aMap.begin(), end=aMap.end();it!=end;++it){
values.push_back((*it).second);
}
return values;
}
Something like that should work
multimap<string, int> m;
vector<int> values;
for (multimap<string, int>::iterator it = m.begin(); it != m.end(); ++it)
{
values.push_back((*it).second);
}