【发布时间】:2019-09-29 03:47:04
【问题描述】:
考虑以下代码(取自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 的第二个参数是否总是一个错误,或者这可能是一个有效的做法吗?
【问题讨论】:
-
erase采用开始和结束迭代器。remove将要删除的项目打乱(某种)到末尾,并返回一个“新结尾”迭代器——它作为要擦除的范围的开始传递给erase函数。您可以创建一个辅助函数,在一次函数调用中为您执行这两项操作。 -
请考虑您可能希望
erase的范围与remove标识的范围不同。 -
不一次性执行这两个操作的一个原因是,在最终擦除容器的尾端。
-
@Eljay -- re: "在最终擦除容器的尾部之前" -- 分离操作的根本原因是算法适用于序列和序列不必有底层容器。也就是说,很可能没有一个容器的尾部必须被移除。
-
在许多语言中,容器本身就是您传递给算法的东西。 但不是在 C++ 中。在 C++ 中,算法不知道容器——它们只知道两个迭代器之间的元素序列。大多数情况下,这两个迭代器来自一个容器(必然是同一个容器)。但有时它们并不代表容器。 (任何给定的容器都可以将算法实现为一种方法,然后该方法就知道容器了。)而 that 就是为什么 remove() 会随机播放元素,但不会 删除 他们。它不知道要从中删除它们的容器。
标签: c++ stl erase-remove-idiom