2012-02-26 2 views
2

Я следующий вектор передается функцииСтирание элемент из вектора

void WuManber::Initialize(const vector<const char *> &patterns, 
         bool bCaseSensitive, bool bIncludeSpecialCharacters, bool bIncludeExtendedAscii) 

Я хочу, чтобы удалить какой-либо элемент, который меньше по длине, чем 2 Я попытался следующие, но она не компилируется даже может вы говорите мне, что мне здесь не хватает.

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 

ответ

1

Это не может работать, потому что если вы удалите что-то из своего вектора, вы аннулируете свой итератор.

Возможно, он не скомпилирован, потому что вы используете свой итератор неправильно. Вы можете попробовать iter-> c_str или (* iter) .c_str. С другой стороны, сообщите нам сообщение об ошибке;)

Следующее, вы пытаетесь изменить вектор const. Вот почему компилятор жалуется.

Вы можете сделать это с индексом, например:

for (int i = 0; i < patterns.size(); ++i) { 
    size_t lenPattern = strlen(patterns[i]); 
    if (2 > lenPattern) { 
     patterns.erase(patterns.begin() + i); 
     --i; 
    } 
} 

Однако, это не очень элегантно, как я манипулировать счетчик ...

+0

Я попробовал ваш сегмент теперь она дает мне: WuManber.cpp: В функции члена Пустота WuManber :: Initialize (Const станд :: вектор &, BOOL, BOOL, BOOL) ': WuManber.cpp: 63: 42 : error: нет подходящей функции для вызова в 'std :: vector :: erase (__ gnu_cxx :: __ normal_iterator >) const' error – user1231229

+1

Вы пытаетесь изменить ссылку на const const , Вот почему компилятор жалуется. – Tim

0

Во-первых, как уже упоминалось Тим, то patterns параметр является ссылкой на const, поэтому компилятор не позволит вам изменить его - измените это, если хотите стирать в нем элементы.

Имейте в виду, что iter 'указывает на' указатель (например, char const*). Таким образом, вы разыменования итератора, чтобы добраться до указателя на строку:

size_t lenPattern = strlen(*iter); 
if (2 > lenPattern) 
iter = patterns.erase(iter); 

Кроме того, в последней строке фрагмента, iter назначается независимо erase() возвращается, чтобы сохранить его действительный итератор.

Обратите внимание, что удаление элемента, на которое указывает iter, не освобождает любую строку, на которую указывает указатель в векторе. Неясно, нужно ли это или нет, поскольку вектор может не «владеть» строками, на которые указывают.

2

В дополнение к проблемам, о которых говорили другие, это плохая идея стирать элементы из вектора, когда вы перебираете его. Есть методы, чтобы сделать это правильно, но он обычно медленный и хрупкий. remove_if почти всегда лучший вариант для многих случайных подчисток из вектора:

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

В C++ 0x вы можете сделать это более сжато с лямбда-функции, но выше, более вероятно, будет работать на немного старше компилятор.

Смежные вопросы