I am using C erase remove idiom and facing a weird problem. If I access element using string index result is not as expected.
string str = "A man, a plan, a canal: Panama";
str.erase(remove(str.begin(), str.end(), str[1]), str.end());
Result : Aman, a plan, a canal: Panaa
and if I use as below, result is as expected.
string str = "A man, a plan, a canal: Panama";
str.erase(remove(str.begin(), str.end(), ' '), str.end());
Result : Aman,aplan,acanal:Panama
CodePudding user response:
Look at the signature of std::remove
:
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
The value
is passed by const reference, therefore after removing first space your str[1]
points to a wrong memory. It's unsafe to access container elements while modifying the container.
CodePudding user response:
The algorithm std::remove
is declared the following way
template<class ForwardIterator, class T>
ForwardIterator remove(
ForwardIterator first, ForwardIterator last,
const T& value // <-- reference!
);
As you can see the third parameter is declared as a reference const T& value
.
So in this call
str.erase(remove(str.begin(), str.end(), str[1]), str.end());
the third argument is a reference to the object str[1]
the value of which is changed within the algorithm to the letter 'm'
when the first character ' '
is encountered..
If you would write for example
str.erase(remove(str.begin(), str.end(), str[1] 0), str.end());
you would get the expected result because in this case the reference refers to a temporary object.