为什么 std::remove 不删除数组的最后一个元素

Why doesn't std::remove remove the last element of my array

本文关键字:最后一个 数组 元素 std remove 为什么 删除      更新时间:2023-10-16

可能的重复:
STL删除无法正常工作?

对不起,我是C 11和迭代器的新手。这应该删除数组中的所有数字3,但不会删除最后一个。为什么?

#include <algorithm>
#include <array>
#include <iostream>
int main() {
   std::array<int, 8> a{{9, 3, 4, 5, 33, 5, 6, 3}};
   int N(3);
   std::remove(a.begin(), a.end(), N);
   for (int i : a) {
      std::cout << i << 'n';
   }
}

我作为输出:

{ 9, 4, 5, 33, 5, 6, 6, 3 }
                        ^
                        |
             // the last 3 is still there

算法不了解基础容器。他们只是根据给出的迭代器进行迭代,并独立于容纳容器的访问元素。这就是为什么有一种称为擦除示例习惯的原因,它采用以下模式:

container.erase(std::remove(it1, it2, value), std::end(container));

std::remove将保留的元素移至前面(谢谢,k-ballo),并将迭代器返回到未换元素的开始。然后, erase擦除了从那点到末端的所有内容。

由于std::array封装了固定大小的数组,我将适应您的 std::vector示例:

std::vector<int> v{9, 3, 4, 5, 33, 5, 6, 3};
v.erase(std::remove(std::begin(v), std::end(v), 3), std::end(v));

唯一要注意的是.begin().end()的更通用形式,它也适用于内置数组。这包含在C 11中。

std::remove在迭代器上操作;因此,它无法实际擦除容器中的元素。这就是为什么它通常与erase一起使用:

a.erase(std::remove(a.begin(), a.end(), N), a.end());

正如其他人所指出的,这对array不起作用。

正如其他人指出的那样,std::remove()不会删除任何元素。如果您需要使用std::array<...>,则仍然可以使用std::remove()并捕获相应的迭代器以确定序列的末尾。您如何获得我不知道的声称的输出(带有卷发和逗号),但这是我如何实施它:

auto end = std::remove(a.begin(), a.end(), 3);
std::cout << "{ ";
if (a.begin() != end) {
    std::copy(a.begin(), end - 1, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << end[-1];
}
std::cout << "}n";