выполните итерации вектора, удалите определенные объекты, когда я иду

Портативность (твоя).

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

Для сравнения, .concat () довольно очевиден и читабелен по сравнению с + в некоторых случаях.

62
задан Ben Voigt 28 August 2013 в 22:05
поделиться

3 ответа

Проверьте std :: remove_if :

#include <algorithm> // for remove_if
#include <functional> // for unary_function

struct delete_file : public std::unary_function<const std::string&, bool> 
{
    bool operator()(const std::string& strPath) const
    {
        return ::DeleteFile(strPath.c_str());
    }
}

m_vPaths.erase(std::remove_if(m_vPaths.begin(), m_vPaths.end(), delete_file()),
                m_vPaths.end());

Используйте std :: list , чтобы решить проблему с недопустимыми итераторами, хотя вы потеряете произвольный доступ . (И производительность кеширования в целом)


Для записи, способ реализации кода будет следующим:

typedef std::vector<std::string> string_vector;
typedef std::vector<std::string>::iterator string_vector_iterator;

string_vector_iterator iter = m_vPaths.begin();
while (iter != m_vPaths.end())
{
    if(::DeleteFile(iter->c_str()))
    {
        // erase returns the new iterator
        iter = m_vPaths.erase(iter);
    }
    else
    {
        ++iter;
    }
}

Но вы должны использовать std :: remove_if (изобретать колесо - плохо).

75
ответ дан 24 November 2019 в 16:33
поделиться

Учитывая время на стирание файла, это, вероятно, не имеет значения, но я бы все же посоветовал повторять вектор в обратном направлении - таким образом вы обычно удаляете элементы из (близко к ) конец вектора. Время, необходимое для удаления элемента, пропорционально количеству элементов, следующих за ним в векторе. Если (например) у вас есть вектор из 100 имен файлов и вы успешно удалили все из них, вы скопируете последний элемент 100 раз в процессе (и скопируете предпоследний элемент 99 раз и т. Д.).

OTOH, если вы начинаете с конца и работаете в обратном направлении, вы не копируете, пока удаление файлов прошло успешно. Вы можете использовать обратные итераторы для обхода вектора в обратном направлении, ничего не меняя. Например, GMan '

7
ответ дан 24 November 2019 в 16:33
поделиться

Метод erase () возвращает новый (действительный) итератор, который указывает на следующий элемент после удаленного. Вы можете использовать этот итератор для продолжения цикла:

std::vector<std::string>::iterator iter;
for (iter = m_vPaths.begin(); iter != m_vPaths.end(); ) {
    if (::DeleteFile(iter->c_str()))
        iter = m_vPaths.erase(iter);
    else
        ++iter;
}
119
ответ дан 24 November 2019 в 16:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: