传递额外的参数给remove_if
Pass additional arguments to remove_if
我想使用remove_if
函数从向量中删除元素,但将擦除限制为N个元素。
的例子:
// predicate function that determines if a value is an odd number.
bool IsOdd (int i) {
if (we deleted more than deleteLimit)
return false;
return ((i%2)==1);
}
void otherFunc(){
int deleteLimit = 10;
// remove odd numbers:
std::vector<int>::iterator newEnd =
std::remove_if (myints.begin(), myints.end(), IsOdd (how to pass deleteLimit?) );
}
我需要IsOdd
谓词存储它删除了多少元素以及我们想要删除多少元素。唯一的方法是使用全局变量?这样的:
int deleteLimit = 10;
int removedSoFar = 0;
bool IsOdd (int i) {
if (deleteLimit < removedSoFar)
return false;
if (i%2==1) {
removedSoFar++
return true;
}
return false;
}
remove_if ...
告诉"到目前为止已经删除了多少元素"的状态应该在函数/算法调用之外定义。这是因为函数函数不应该有一个在被调用时被修改的状态(这将是未定义的行为)。
你应该在函子的构造函数中引用这个状态(计数器)(或者在lambda中通过引用捕获),这样你就可以访问和修改这个计数器。当复制此函子时,算法调用哪一个都无关紧要,因为它们现在都保持对相同状态的引用。
使用函子(c++ 03):
class IsOdd {
int deleteLimit;
int & deletedSoFar;
public:
IsOdd(int deleteLimit, int & deletedSoFar) :
deleteLimit(deleteLimit), deletedSoFar(deletedSoFar)
{}
bool operator()(int i) const {
if (deletedSoFar < deleteLimit && i % 2) {
++deletedSoFar;
return true;
}
return false;
}
};
int deletedSoFar = 0;
int deleteLimit = 10;
std::remove_if (myints.begin(), myints.end(), IsOdd(deleteLimit, deletedSoFar));
使用lambda (c++ 11):
int deletedSoFar = 0;
int deleteLimit = 10;
auto it = std::remove_if (myints.begin(), myints.end(), [deleteLimit,&deletedSoFar](int i){
if (deletedSoFar < deleteLimit && i % 2) {
++deletedSoFar;
return true;
}
return false;
});
myints.erase(it, myints.end());
除了创建自己的函子,还可以传递lambda表达式:
auto deleteLimit = 25;
auto removedSoFar = 0;
auto it = remove_if (myints.begin(),
myints.end(),
[deleteLimit, &removedSoFar](int i)->bool
{
if ( (deletedSoFar < deleteLimit) && (i % 2)) {
++deletedSoFar;
return true;
}
return false;
} );
// really remove the elements from the container
myints.erase(it, myints.end());
然而,要注意状态函数和std库算法并不总是很好的混合。在这里,对lambda的调用可能有副作用,因此您无法保证序列中的哪些元素将被删除。
注意最后一次呼叫std::vector::erase
。这是真正从容器中删除不需要的元素所必需的。参见erase remove习语
int initial_size = myints.size();
std::remove_if (myints.begin(), myints.end(), [myints.size(),limit,initial_size](int i)->bool{
return ( ( initial_size-myints.size() )<limit ? i%2 : false) } );
使用functor
,与operator ()
结构,或使用一些绑定特性(std::bind/boost::bind)
bool isOdd(int current, int limit, int& count)
{
if (count >= limit)
{
return false;
}
if (current % 2 == 1)
{
++count;
return true;
}
return false;
}
int count = 0, limit = 10;
vec.erase(std::remove_if(vec.begin(), vec.end(),
std::bind(&isOdd, _1, limit, std::ref(count)), vec.end());
和函子
struct IsOdd : public std::unary_function<int, bool>
{
public:
IsOdd(int l) : count(0), limit(l)
{
}
bool operator () (int i)
{
if (count >= limit)
{
return false;
}
if (current % 2 == 1)
{
++count;
return true;
}
return false;
private:
int count;
int limit;
};
int limit = 10;
vec.erase(std::remove_if(vec.begin(), vec.end(),
isOdd(limit)), vec.end());
投票结果中的代码有一个小错误。在operator关键字前缺少圆括号。我无法编辑,因为它少于六个字符,我无法评论,因为我的分数太低。
class IsOdd {
int deleteLimit;
int & deletedSoFar;
public:
IsOdd(int deleteLimit, int & deletedSoFar) :
deleteLimit(deleteLimit), deletedSoFar(deletedSoFar)
{}
bool operator()(int i) const {
if (deletedSoFar < deleteLimit && i % 2) {
++deletedSoFar;
return true;
}
return false;
}
};
int deletedSoFar = 0;
int deleteLimit = 10;
std::remove_if (myints.begin(), myints.end(), IsOdd(deleteLimit, deletedSoFar));
相关文章:
- 我的简单if-else语句是如何无法访问的代码
- 使用函数"remove"删除重复元素
- 如何将enable-if与模板参数和参数包一起使用
- 无论条件是否为true,if总是在c++中执行
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何删除peer if else分支中的冗长句子
- 链表的泛型函数remove()与成员函数remove)
- 我似乎对if/else的基本语句有问题:/
- if数组上的随机数
- 将按位if条件转换为普通if条件
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 使用if-else将数字转换为单词
- 为什么简单的算术减法在"if"条件下不起作用?