Runtime exception when using vector.insert() [duplicate] - c++

This question already has answers here:
Vector iterator erase giving me a runtime error?
(2 answers)
Replacing elements in vector using erase and insert
(3 answers)
Erasing from a std::vector while doing a for each?
(1 answer)
Closed 1 year ago.
So I have the following code, which is supposed to use an iterator to replace an element in a vector if it matches some given value "old".
using StringIter = std::vector<std::string>;
using StringVec = std::vector<std::string>;
void replace(StringVec ref, std::string old, std::string replacement)
{
for (StringIter::iterator it = ref.begin(); it != ref.end(); it++)
{
if (*it == old)
{
ref.erase(it);
ref.insert(it,replacement);
}
}
}
However, I get the following runtime error: "vector emplace iterator outside range". I've tried changing the order of erase and insert, and using insert(it-1,...) instead, but it doesn't work. Haven't found any solution to this exact problem after an hour or so of googling.

Related

erase entire C++ vector [duplicate]

This question already has answers here:
Delete all items from a c++ std::vector
(9 answers)
Closed 2 years ago.
I would like to know which of the following version is the more appropriate to empty a vector, or if there is even a better way:
std::vector<T> v;
// 1
v.erase(v.begin(), v.end());
// 2
v = {};
My thought is that one has a complexity greater than the other, but one saves memory reallocation...
None. The idiomatic way is to call clear();:
std::vector<T> v = { ... };
v.clear();

std::list insert() invalidates iterator? [duplicate]

This question already has answers here:
How to invalidate an iterator?
(4 answers)
What is iterator invalidation?
(3 answers)
Closed 4 years ago.
Say I have a simple program as so:
int main(void) {
std::list<int> l;
auto it = l.begin();
auto it2 = l.insert(l.begin(), 5);
std::cout << (it == it2) << std::endl;
}
Doesn't this show that the iterator it has been invalidated by inserting into the list. Yet the C++ standard says that insertion into a list does not invalidate iterators.
Originally it would probably hold a nullptr since the list was empty. Now it no longer points to any iterator part of the list. So is it not invalidated?

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

Can reverse iterator be used as normal iterator? [duplicate]

This question already has answers here:
How to call erase with a reverse iterator
(13 answers)
Closed 6 years ago.
Is something wrong with erasing with reverse iterator? When compiling the code fragment below, I receive 'no matching function' error when using 'rit' as argument for erase().
std::vector<MyRecord*>* BLV = GetVector;
for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end(); ++it)
BLV->erase(it);
for (std::vector<MyRecord*>::reverse_iterator rit = BLV->rbegin(); rit != BLV->rend(); ++rit)
BLV->erase(rit);
Indeed erase cannot be used directly with a reverse iterator; you'd essentially be removing the wrong element if it were allowed.
You need to convert rit to a forward iterator.
(rit + 1).base(); will give you the equivalent it. Note carefully the + 1.
Putting this together, write
BLV->erase((rit + 1).base());
in your reverse case.

go through map c++ [duplicate]

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/