当 std::remove_if 在 erase-remove 习语中使用不当时,std::erase 不会返回错误

问题描述 投票:0回答:0

我们知道,erase-remove 习语可以用作删除向量元素的简洁模式。

特别是,std::remove_if 交换向量内的元素,以便将所有与谓词不匹配的元素放在容器的开头。然后将这些元素从容器中移除。

这也意味着如果谓词(lambda 函数的主体)返回 true,则该元素将被放置在向量的末尾。

必须注意,在 erase remove 习语中,erase 和 remove 函数都必须将迭代器获取到同一容器。这意味着如果我尝试在 remove_if 语句中提供不同的迭代器,擦除函数必须返回错误。

但是考虑下面的代码:

vector<int> valsToRemove{ 4, 5, 6, 2, 3, 7, 10 };
    
vector<int> isValidToRemove{ 0, 1, 0, 1, 1, 0, 1 };
    
valsToRemove.erase(std::remove_if(isValidToRemove.begin(),
                                isValidToRemove.end(),
                                [&](int& x)-> bool { return x == 0; }), valsToRemove.end() );
                                
for( auto& val: valsToRemove ) {
        cout << val << "\t";
}

事实证明,我有一个向量

isValidToRemove
,它告诉我是否必须根据“0”或“1”值保留或删除
valsToRemove
向量的元素。我在 remove_if 语句中使用它来满足谓词。在这种情况下,由于 erase 和 remove_if 函数中使用了不同的容器,erase 函数必须返回错误。

但是,我得到了一个任意输出,它以某种方式附加了向量的其他元素。输出也因不同的实例/机器而异。

4 5 6 2 3 7 10 0 0 0 49 0 1 1 1 1

我只是想确认这是否应该是正确的行为,或者是否应该修改它以便将正确的错误返回给此函数的用户/客户端。

此外,是否有一种简洁的方法或特定的模式来使用单独的向量(例如上面示例中的

isValidToRemove
,它可能从上游组件接收)来删除不同向量的元素(示例中的
valsToRemove
上面)而不是仅仅使用 for 循环来删除这些元素。

c++ c++11 stdvector erase-remove-idiom
© www.soinside.com 2019 - 2024. All rights reserved.