go through map c++ [duplicate] - c++

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/

Related

C++ map container erase() segmentation fault [duplicate]

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;
});

C++ List Iteration and erasing [duplicate]

This question already has answers here:
iterate vector, remove certain items as I go
(3 answers)
Closed 6 years ago.
EDIT: This question refers specifically to std::lists - other similar questions on Stack Overflow refer to std::vectors
I'm using C++ and having trouble erasing an element from a std::list while iterating through it. I have a list of a custom class ('Objects' for the sake of this question), and my code looks like this:
for(auto i : Objects)
if(i.EraseFlag == true)
{
i = Objects.erase(i);
}
I'm getting the error: 'no matching function for call to std::list::erase(Object&)'
I believe this is the right way (as of C++11) to iterate through lists, erase an element and return an iterator that takes into account the erasure, but clearly I'm doing something wrong. Previously when using vectors I would use 'Objects.erase(Objects.begin() + i)' with i being an integer in a for loop, but given the access requirements of lists this won't work.
Help appreciated.
Thanks
Member function erase deals with iterators.
For such a task it would be correctly to use an ordinary for loop. For example
for ( auto it = Objects.begin(); it != Objects.end(); )
{
if ( it->EraseFlag ) it = Objects.erase( it );
else ++it;
}
Another approach is to use member function remove_if. For example
Objects.remove_if( []( const auto &value ) { return value.EraseFlag; } );

Clarification of iterating through maps using for(auto iter : value) [duplicate]

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)
{
//
}

C++ loop through map while erasing [duplicate]

This question already has answers here:
What happens if you call erase() on a map element while iterating from begin to end?
(3 answers)
Closed 9 years ago.
To loop through a map in c++ we do sth like this
map<string,int> mymap;
map<string,int>::iterator it= mymap.begin();
while(it!=mymap.end()) {
//code here
it++;
}
What if in the "code here" part i have an if statement that if evaluated to true, it erases one element from the map? How should my code change so that it still loops through all mymap elements in order?
http://en.cppreference.com/w/cpp/container/map/erase :
References and iterators to the erased elements are invalidated. Other
references and iterators are not affected.
(So make sure you increment and save a "next" iterator before you erase.
Edit: In fact since C++11, erase returns the next iterator anyway, so you may use that.)
you may want to reassign your iterator when you erase an element, as it wont be valid otherwise...
it = mymap.erase(...)
To avoid using the iterator after invalidating it when erasing, the loop body should be like this:
if (should_erase) {
it = my_map.erase(it); // C++11: returns the next iterator
my_map.erase(it++); // Historic C++: no helpful return value
} else {
++it;
}

Is there any way to validate the iterator of an STL container? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Best way to check if an iterator is valid
Let's say I have a function which takes an iterator as its sole parameter as below.
void DoSomethingWithIterator(std::vector<int>::iterator iter)
{
// Check the pre-condition
assert( /* how to validate iter here? */ )
// Operate on iter afterwards
..
}
How do I know if iter is valid or not. By valid, I mean it points to a existing element inside the vector, e.g., from m_intVector.begin() to m_intVector.end().
In general, you can't do that. C++ types are designed to be maximally efficient and don't contain such additional information.
For example, vector's iterator is likely to be equivalent to a pointer to element (this is the case on my machine, using g++ 4.7.2).
> I mean it points to a existing element inside the vector, e.g., from m_intVector.begin() to m_intVector.end().
Sure. Just iterate through the contents of m_vector, and compare each iterator to iter.
for ( std::vector<int>::iterator it = m_intVector.begin (); it != m_intVector.end (); ++it )
if ( it == iter ) return true;
return false;
But I suspect that you won't want to pay for that kind of checking.