C++ 为什么';t std::删除数组的最后一个元素

C++ 为什么';t std::删除数组的最后一个元素,c++,C++,可能重复: 对不起,我是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.e

可能重复:

对不起,我是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';
   }

}

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

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

正如其他人所指出的,这对迭代器上的
数组
std::remove
操作不起作用;因此,它实际上无法从容器中删除元素。这就是为什么它通常与擦除一起使用的原因:

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

正如其他人所指出的,这不适用于
数组

算法不了解底层容器。它们只是根据给定的迭代器进行迭代,并独立于包含它们的容器访问元素。这就是为什么有一种称为“擦除-删除”的习惯用法,它采用以下模式:

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));
std::向量v{9,3,4,5,33,5,6,3};
v、 擦除(std::remove(std::begin(v)、std::end(v)、3)、std::end(v));

唯一需要注意的是
.begin()
.end()
的更一般形式,它也适用于内置阵列。这包含在C++11中。

算法不了解底层容器。它们只是根据给定的迭代器进行迭代,并独立于包含它们的容器访问元素。这就是为什么有一种称为“擦除-删除”的习惯用法,它采用以下模式:

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));
std::向量v{9,3,4,5,33,5,6,3};
v、 擦除(std::remove(std::begin(v)、std::end(v)、3)、std::end(v));

唯一需要注意的是
.begin()
.end()
的更一般形式,它也适用于内置阵列。这包含在C++11中。

正如其他人指出的,
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";
auto-end=std::remove(a.begin(),a.end(),3);

std::cout正如其他人指出的,
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";
auto-end=std::remove(a.begin(),a.end(),3);

std::cout
std::array
无法更改其大小。使用
std::vector
std::array
无法更改其大小。使用
std::vector
remove
不会将删除的元素移到后面,而是将保留的元素移到前面。后面的元素有一个未指定的值。@K-ballo,哦,我没意识到。我快忘了。我稍后再修复。
remove
不会将删除的元素移到后面,而是将保留的元素移到前面。后面的元素有一个未指定的值。@K-ballo,哦,我没意识到。我快忘了。稍后我会修复它。在这种情况下,
std::remove
在做什么?我知道它返回了一个迭代器,但这(除了给它的参数外)如何影响
erase
处理它呢?@David:chris在他的回答中解释得很好。如果您阅读参考,那么
remove
所做的就是将所有保留的元素移到前面,有效地移除您想要移除的元素,并将所有实际用途都是垃圾的元素留在序列的后面。
erase
所做的是清理
remove
留下的垃圾。在这种情况下,
std::remove
在做什么?我知道它返回了一个迭代器,但这(除了给它的参数外)如何影响
erase
处理它呢?@David:chris在他的回答中解释得很好。如果您阅读参考,那么
remove
所做的就是将所有保留的元素移到前面,有效地移除您想要移除的元素,并将所有实际用途都是垃圾的元素留在序列的后面。
擦除
所做的是清除
删除
留下的垃圾。