如果我在std :: remove函数中直接传递数组元素ar [0]而不是x,为什么会得到不同的结果?

问题描述

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

int main()
{
    vector<int> ar = {1,2,3,4,5,6,7};
    vector<int> sum;
    int n = ar.size();
    for (int i = 0; i < n; i++)
    {
        int x = ar[0];
        int frq = count(ar.begin(),ar.end(),x);
        int q = frq / 2;
        sum.push_back(q);

        ar.erase(remove(ar.begin(),x),ar.end()); // Doubt
    }
    int count = 0;
    int n1 = sum.size();
    for (int i = 0; i < n1; i++)
    {
        count = count + sum[i];
    }
    cout << count;
}

如果我在x函数中直接传递ar[0]而不是std::remove,为什么会得到不同的结果?

xar[0]具有相同的值。

解决方法

原因是std::remove通过引用采用了最后一个参数。来自cppreference

因为std :: remove通过引用获取值,所以如果引用范围为[first,last)的元素,则它可能具有意外行为。

这有点棘手,因为参数是作为const引用传递的:

template< class ForwardIt,class T >
ForwardIt remove( ForwardIt first,ForwardIt last,const T& value );

但是,仅因为ar[0]作为const引用被传递并不意味着ar[0]不能通过其他方式修改。在这种情况下,可以通过first / last对其进行修改。实际上,我无法想到在[first,last)内将元素设为value是“好的”情况。

为便于说明,请考虑使用ar[0]会得到相同的错误输出,就好像您声明x作为参考:

int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());

此处x作为const引用传递,但是算法确实修改了ar[0]