Etienne Armangau
Etienne Armangau

Reputation: 223

How unsafe is it to use std::prev with string_iterator.begin()?

i have this piece of code. This function doesn't copy adjacent duplicates chars.It keeps only one of them. To do shorter, i've decided to use std::prev with iterator.begin(). I know that it's a (very) bad practice, i come from C, but in C++ is somewhat different. The undefined behavior is almost non existent. Tell me guys. I could change my method easily. If you have a faster method, i'm interested too.

string suppDouble(const string& 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;
}

Upvotes: 2

Views: 901

Answers (2)

Timo
Timo

Reputation: 9825

std::prev effectively does it - 1 in your case. However, it is undefined behavior to decrement a begin iterator.

Bidirectional iterator:

The begin iterator is not decrementable and the behavior is undefined if --container.begin() is evaluated

This means, that your very first loop iteration is already UB.

Note that there is an std algorithm that does exactly what you want: std::unique:

Eliminates all except the first element from every consecutive group of equivalent elements from the range [first, last) and returns a past-the-end iterator for the new logical end of the range.

Upvotes: 4

Huy Nhat Tran
Huy Nhat Tran

Reputation: 145

Think of iterator in C++ like pointer. If you don't boundary check carefully, it can point to data that doesn't belong to you. It cause std::out_of_range exception

Upvotes: 1

Related Questions