Reputation: 61
I have the following vector passed to a function
void WuManber::Initialize( const vector<const char *> &patterns,
bool bCaseSensitive, bool bIncludeSpecialCharacters, bool bIncludeExtendedAscii )
I want to erase any element that is less in length than 2 I tried the following but it didn't compile even can you tell me what I am missing here.
for(vector<const char *>::iterator iter = patterns.begin();iter != patterns.end();iter++)
{//my for start
size_t lenPattern = strlen((iter).c_str);
if ( 2 > lenPattern )
patterns.erase(iter);
}//my for end
Upvotes: 2
Views: 2044
Reputation: 7324
On top of the problems others have pointed out, it's a bad idea to erase items from the vector as you iterate over it. There are techniques to do it right, but it's generally slow and fragile. remove_if
is almost always a better option for lots of random erasures from a vector:
#include <algorithm>
bool less_than_two_characters(const char* str) { return strlen(str) < 2; }
void Initialize(vector<const char*>& v) {
v.erase(std::remove_if(v.begin(), v.end(), less_than_two_characters), v.end());
}
In C++0x you can do that more concisely with a lambda function but the above is more likely to work on a slightly older compiler.
Upvotes: 2
Reputation: 340168
First, as Tim mentioned, the patterns
parameter is a const reference, so the compiler won't let you modify it - change that if you want to be able to erase elements in it.
Keep in mind that iter
'points to' a pointer (a char const*
to be specific). So you dereference the iterator to get to the string pointer:
size_t lenPattern = strlen(*iter);
if ( 2 > lenPattern )
iter = patterns.erase(iter);
Also, in the last line of the snippet, iter
is assigned whatever erase()
returns to keep it a valid iterator.
Note that erasing the element pointed to by iter
will not free whatever string is pointed to by the pointer in the vector. It's not clear whether or not that might be necessary, since the vector might not 'own' the strings that are pointed to.
Upvotes: 0
Reputation: 2081
This cannot work, because if you erase something from your vector you invalidate your iterator.
It probably does not compile because you use your iterater in a wrong way. You might try iter->c_str or (*iter).c_str. On the other hand, give us the error message ;)
Next thing, you try to modify a const vector. This is why the compiler is complaining.
You could do this with an index, like this:
for (int i = 0; i < patterns.size(); ++i) {
size_t lenPattern = strlen(patterns[i]);
if (2 > lenPattern) {
patterns.erase(patterns.begin() + i);
--i;
}
}
However, this is not very elegant, as I manipulate the counter...
Upvotes: 1