17

考虑以下代码(取自cppreference.com,稍作修改):

#include <algorithm>
#include <string>
#include <iostream>
#include <cctype>

int main()
{
    std::string str1 = "     Text with some   spaces";
    str1.erase(std::remove(str1.begin(), str1.end(), ' '), str1.end());
    std::cout << str1 << '\n';

    return 0;
}

为什么第二个参数是erase必要的?(即str1.end()在这种情况下。)

为什么我不能只提供 to 返回的迭代removeerase?为什么我还必须告诉它要擦除的容器的最后一个元素?

这里的陷阱是你也可以在erase没有第二个参数的情况下调用,但这显然会产生错误的结果。

是否存在我不想将容器的末尾作为第二个参数传递给的用例erase

省略erase擦除删除习语的第二个参数总是一个错误,或者这可能是一个有效的事情吗?

4

1 回答 1

18

std::remove返回一个迭代器;它是序列的新的结束迭代器。但是当序列由容器管理时,容器的大小并没有改变;std::remove打乱序列中元素的顺序,但实际上并没有删除它们中的任何一个。

为了摆脱容器中不属于您调用的新序列的元素,当然,container.erase(). 但目标是删除所有额外的元素;只用一个迭代器调用container.erase()告诉它删除那个元素。要告诉container.erase()擦除“从这里到结束”的所有内容,您必须告诉它“这里”哪里以及结束在哪里。所以这意味着两个迭代器。

如果有帮助,请将“删除/擦除”习语视为两个单独的步骤:

auto new_end = std::remove(str1.begin(), str1.end(), ' ');
str1.erase(new_end, str1.end());
于 2019-05-11T14:18:22.850 回答