Насколько небезопасно использовать std::prev с помощью string_iterator.begin()?

#c #iterator #undefined-behavior

Вопрос:

у меня есть этот фрагмент кода. Эта функция не копирует соседние повторяющиеся символы.В нем хранится только один из них. Чтобы сделать короче, я решил использовать std::prev с iterator.begin(). Я знаю, что это (очень) плохая практика, я родом из C, но в C все несколько иначе. Неопределенное поведение почти не существует. Скажите мне, ребята. Я мог бы легко изменить свой метод. Если у вас есть более быстрый метод, мне тоже интересно.

 string suppDouble(const stringamp; str)
{
    if (str.size() <= 1) return str;

    string token;
    for (auto it = str.cbegin(); it != str.cend(); it  )
    {
        if (*(std::prev(it)) != *it) token.push_back(*it);
    }
    return token;
}
 

Комментарии:

1. Это просто УБ. Вы не должны получать доступ к элементу раньше begin .

Ответ №1:

std::prev эффективно работает it - 1 в вашем случае. Однако уменьшение итератора begin является неопределенным поведением.

Двунаправленный итератор:

Итератор begin не может быть уменьшен, и поведение не определено, если вычисляется —container.begin()

Это означает, что ваша самая первая итерация цикла уже UB.

Обратите внимание, что существует алгоритм std, который делает именно то, что вы хотите: std::unique :

Удаляет все, кроме первого элемента, из каждой последовательной группы эквивалентных элементов из диапазона [первый, последний) и возвращает итератор конца для нового логического конца диапазона.

Комментарии:

1. точно, я не думал об уникальности. я глупая, ха-ха

Ответ №2:

Подумайте об итераторе в C , как о указателе. Если вы не будете тщательно проверять границы, это может указывать на данные, которые вам не принадлежат. Это вызывает std::out_of_range исключение

Комментарии:

1. Я прекрасно знаю, что это значит, но с этим кодом я никогда не сталкивался с неопределенным поведением или исключением. Вот почему я обратился к вам, ребята. Очевидно, что здесь есть что-то уникальное. Проблема решена

2. я никогда не сталкивался с неопределенным поведением . Вы думаете , что не сталкивались с этим, но в вашем коде есть UB.

3. Возможно, вы наверняка правы, но я хотел быть уверенным, что это UB. В C это гораздо более жестоко, когда есть UB.

4. Я думаю, что именно по этой причине он и позвонил undefined behavior . Это непредсказуемо