tags:

views:

46

answers:

2

I've read here on StackOveflow and other sources that the behavior of the remove function is simply re-ordering the original container so that the elements that are TO BE REMOVED are moved to the end of the container and ARE NOT deleted. They remain part of the container and the remove() function simply returns an iterator that delimits the end of the range of elements to keep.

So if you never actually trim off the portion of the container that has the values that have been 'removed', they should still be present.

But when I run the code below there are no trailing spaces after the alphanumeric characters that were not 'removed'.

int main()
{
    std::string test "this is a test string with a bunch of spaces to remove";
    remove(test.begin(), test.end(), ' ');
    std::cout << test << std::endl;

    return 0;
}

What is going on here? Seeing as I never call test.erase() shouldn't I have a bunch of trailing spaces on my string? Is it guaranteed that the 'removed' items will still be present after calling remove()?

PS-I'm not looking for suggestions on how to best remove spaces from a string, the above is simply an illustrative example of the remove() behavior that is confusing me.

+1  A: 

What's left at the end of your container after a call to remove is not necessarily the elements that were removed. It's just junk. Most likely it's "whatever was in those positions before the call to remove", but you can't rely on that either. Much like an uninitialized variable, it could be anything.

For example, the string:

"Hi I am Bob!\0"

after a call to remove to get rid of spaces probably looks like this

"HiIamBob!\0b!\0"

You won't see that on a cout, though, because it will stop printing once it hits the '\0'.

Tyler McHenry
Ok, that's kinda what I suspected. The documentation that I've been looking at (http://www.cplusplus.com/reference/algorithm/remove/) seems pretty confident that they are left in place and are accessible.Thought maybe this was one of those cases of undefined behavior that can be implementation specific.
MTLPhil
You may be right on that, actually. I thought it was implementation specific, but that documentation seems to contradict me (although cplusplus.com is not always the most accurate resource). Either way, the contents of the container after the new `end` are definitely *not* the removed elements.
Tyler McHenry
Just saw the example you added. Good point. Thanks.
MTLPhil
Just checked out my copy of the C++ standard, it the section on `std::remove` does *not* seem to require anything specific about the elements in the container after the new end.
Tyler McHenry
Yeah, I think I've misunderstood what it's doing. It's not actually moving things around so much as duplicating things forward which can overwrite some of the stuff that should be 'removed'.What I was picturing in my head is more like the behavior of partition() or stable_partition().
MTLPhil
A: 

You might be willing to get Boost.String.

It's a collection of algorithms to act on strings.

boost::erase_all(test, " ");
Matthieu M.