C++中使用remove_if时出现意外行为

6
我尝试使用std::remove_if来从简单字符串中删除空格,但结果很奇怪。可以有人帮助我弄清楚发生了什么吗?
代码如下:
#include <iostream>
#include <algorithm>
#include <string>

int main(int argc, char * argv[])
{
    std::string test = "a b";
    std::remove_if(test.begin(), test.end(), isspace);
    std::cout << "test : " << test << std::endl; 

    return 0;
}

我预计这应该只会简单地打印出:
test : ab

但是我却得到了:
test : abb

尝试使用另一个字符串,我得到:

输入:"a bcde uv xy"

输出:"abcdeuvxy xy"

似乎是复制了最后一个“单词”,但有时会添加一个空格。如何才能使其只删除所有空格而不出现奇怪的情况?


1
看一下第一个笔记,它可以帮助你解决问题。 - whiskeyo
1个回答

11

std::remove_if 函数通过移动元素来实现 删除 操作,实际上被 删除 的元素并没有从容器中 擦除。STL算法没有这样的特权,只有容器才能删除它们的元素。

(强调是我自己加的)

删除操作是通过移动(使用移动赋值)区间内的元素实现的,使得不需要删除的元素出现在区间的开头。剩余元素的相对顺序被保留,而容器的物理大小不会改变。指向新逻辑结尾和物理结尾之间的元素的迭代器仍然可以解引用,但元素本身的值是未指定的(根据MoveAssignable后置条件)。通常会在调用 remove 后紧接着调用容器的 erase 方法,以擦除未指定值并将容器的物理大小减小到匹配其逻辑大小

您可以在删除元素之后使用 erase 函数(这就是所谓的 erase-remove 习惯用法)。

test.erase(std::remove_if(test.begin(), test.end(), isspace), test.end());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接