对于 erase-remove 习语,为什么第二个参数是必需的,它指向容器的末尾?

For the erase-remove idiom, why is the second parameter necessary which points to the end of the container?

考虑以下代码(摘自 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()。)

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

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

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

对于擦除-删除习惯用法,省略 erase 的第二个参数是否总是一个错误,或者这是一个有效的做法吗?

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

要去掉容器中不属于你调用的新序列的元素,当然是container.erase()。但目标是删除 all 多余的元素;只用一个迭代器调用 container.erase() 告诉它删除 那个元素 。要告诉 container.erase() 擦除所有 "from here to the end" 你必须告诉它 both "here" 在哪里和结束在哪里。所以这意味着两个迭代器。

如果有帮助,请将 "remove/erase" 成语视为两个独立的步骤:

auto new_end = std::remove(str1.begin(), str1.end(), ' ');
str1.erase(new_end, str1.end());