стереть элемент из вектора - PullRequest
2 голосов
/ 26 февраля 2012

У меня есть следующий вектор, переданный в функцию

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

Ответы [ 3 ]

2 голосов
/ 26 февраля 2012

Помимо проблем, на которые указывали другие, плохая идея - удалять элементы из вектора во время итерации по нему.Есть методы, чтобы сделать это правильно, но обычно это медленно и хрупко.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 вы можете сделать это более кратко с помощью лямбда-функции, но описанное выше с большей вероятностью будет работатьна чуть более старом компиляторе.

1 голос
/ 26 февраля 2012

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

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

Далее вы пытаетесь изменить константный вектор. Вот почему компилятор жалуется.

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

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

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

0 голосов
/ 26 февраля 2012

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

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

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

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

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

...